This code was written as part of my PhD research in field robotics, specifically for robotic informative sampling in natural environments. The code is written in Julia for speed and code flexibility.
The purpose of this repository is mainly to serve as a reference implementation for the methods in my thesis. However, the code is organized and documented to make it easier for others to use and build off it. In particular, it contains two reusable submodules that contain core informative sampling and utility pieces. If you have questions about the code or problems trying to use it, feel free to post in the Discussions or Issues, and I’ll see how I can help.
Some packages used by this code used to be submodules within it: GridMaps, AStarGridSearch, MultiQuantityGPs.
See a video of an example run here.
Download Julia and run installer: https://julialang.org/downloads/
Recommended to add julia to your path.
Use git to clone the repository to a local directory:
git clone https://github.com/ngharrison/RoboticInformativeSampling.gitThis will create a directory called RoboticInformativeSampling. Next run julia RoboticInformativeSampling/setup.jl. After that finishes, you should be good to go.
To see an example run of the project in its current state, after following the steps in Installation and Setup,
- Navigate into the
RoboticInformativeSamplingdirectory on the command line - Run
julia --project=app app/missions/example.jl
Normally you will want to run code from within the REPL since this keeps data around after it finishes and saves compilation so it goes much faster on repeated runs. To do this,
- Navigate into the
RoboticInformativeSamplingdirectory on the command line - Run
julia --project=appto open the REPL with the app environment activated - Run
include("app/missions/example.jl")
To understand more about the code and the Julia language in general, go to the documentation.
The easiest way to start using the code for your own purposes is to copy the example.jl file and change the data and settings to fit what you need. You can also look through the other files in app/missions/ for inspiration, such as aus.jl for use with real data and ros_test.jl for use with ROS topics.
An interesting and flexible mission is found in user.jl. This script does all the normal mapping and automatic sample location selection, but it asks for user input for every sample measurement.
The --project=<path> flag automatically activates a project environment after starting the REPL. You can run this manually by ]activate <path> within the julia REPL. Both of these forms accept the path to the directory that contains the Project.toml file, e.g. the app directory of this repository. If you are already within a project directory, you can simply run it without a value (julia --project) with the same effect.
When developing the code, you’ll want to install Revise.jl in order to reload code you’ve changed while using an open REPL. Follow these steps and you won’t have to worry about it again.
- Start the julia REPL in the default environment (
julia) - Run
]add Revise - Exit the REPL (
C-d) - Run
mkdir -p ~/.julia/config && echo "using Revise" >> ~/.julia/config/startup.jl
You can read a bit more about this in the docs.
The project includes code to communicate with other nodes in the Robot Operating System (ROS). Specific missions use rospy, typically through the module in app/ros/ROSInterface.jl, and require a working rospy installation. They have been designed to work with ROS 1 and have been tested on Melodic and Noetic. These ROS features will work just by running the code as normal from the command line or within the Julia REPL.
In addition, this project can be used as a ROS package itself by simply putting it inside your workspace source directory (e.g. catkin_ws/src). It works similar to using a ROS python package because it uses rospy behind the scenes. To test your ROS+Julia setup, run the following:
catkin_makefrom the ROS workspace directory. devel/setup.bashto source the workspaceroscore &to start roscore in the backgroundrosrun informative_sampling ros_test.jl
If the sampling mission runs without errors, everything is working. This script starts up two helper scripts first so it has something to talk to, performs its informative sampling mission, and then closes everything.
If you want to do this with other files, they will need to be executable and have the following code at the top for this to work (and be in the app/missions or app/ros directory):
#!/usr/bin/env julia
using Pkg
Pkg.activate(Base.source_dir() * "/..")You can also just run the same script from within the Julia REPL as described above. The Julia code handles the actual connections to ROS and rosrun is just a convenience to find the executable scripts within the package. It also doesn’t provide maintaining compilation and variables (for inspection) like the REPL does.
ROS-related helper files are generally found in the app/ros directory.
This package has a number of services that can be called from other languages (e.g. Python, C++) through the ROS service protocol. The files describing these are contained in the srv directory:
- GenerateBeliefModel.srv
- GenerateBeliefMaps.srv
- GenerateBeliefMapsFromModel.srv
- NextSampleLocation.srv
- BeliefMapsAndNextSampleLocation.srv
These expose the main parts from the package core: creating belief models, belief maps, and choosing new locations to sample. This is useful if you want to build up an application of your own and embed some of the functionality from this package.
The services do not expose all the options and features of this package. As a main example, they do not handle an entire sampling run since they don’t provide methods for the actual sampling — those would have to be written on the client side. If you want to use all the features of the package, you will need to run the Julia code itself.
To use the services, run the app/ros/server.jl script (after setting up the ROS package as above):
rosrun informative_sampling server.jlTo see how to call each service, look at the examples in the app/ros/client_sim.py script.
The code in this repository can be used from python through pyjulia. You will need to follow the instructions in their documentation to install the Julia package for python (within the RoboticInformativeSampling directory):
python -m pip install --user julia
python -c "from julia import Pkg, install; Pkg.activate('app'); install()"If there are problems running code after the install, you may need to use ~/.local/bin/python-jl instead of python for the rest of the commands.
See app/missions/from_python.py for how one might run the Julia code from within python. If writing your own code, you will need to learn how the pyjulia package passes data structures between the two langauges. To run the script:
python app/missions/from_python.pyNote that just the same as when running Julia code normally, if the interpreter process ends, all compilation will disappear. That means running scripts straight from the command line has to pay the start-up cost every time. If instead the code is run from within a python shell, it will keep compiled methods around and subsequent runs will go much faster.
If you get: Error: Unable to load the 'rospy' python package!
- Run
ENV["PYTHON"] = "/usr/bin/python"(or whatever the path is to the python executable that has the rospy package installed) - Run
]build PyCall - Restart the julia REPL
If you get: ERROR: LoadError: PyError ... ROSInterruptException('rospy shutdown',) from within the Julia REPL, this indicates that you interrupted a previous running ROS node (using ctrl-c) and a new node can’t be created because that flag sticks around inside the same Julia process. You will need to close and reopen the REPL to run new nodes again.
The docs can be viewed at https://ngharrison.github.io/RoboticInformativeSampling.
If you want to view the docs locally, first generate them by running the following command(s) from the project root:
julia --project=docs -e "using Pkg; Pkg.instantiate()" # only needed first time
julia --project=docs docs/make.jlThen open docs/build/index.html in a web browser.
To test that some of the core functionality of the package is working, run the following commands from the project root:
- Open a Julia REPL using
julia --project=core - Run
]test