Development of Obelisk
This page concerns details about developing the core of Obelisk, not how to use Obelisk in a downstream project.
– This page is a work in progress as we continue to update Obelisk –
Overview
We use the following tools for development:
Bash shell (some of the scripts will modify your
.bashrc)Docker and Docker Compose for isolating system states and for development containers
ruffandpyrightfor linting, code-style enforcement, and type checking of Python codeclang-tidyandclang-formatfor C++ codepre-commitfor registering code checks as commit hookspytestfor python code tests
We ensure that all code checks pass in a CI workflow before allowing PRs to merge into main.
Getting Started
To work in Obelisk, both as a dev and as a user, we suggest working in a docker container. Previously we had also supported pixi, but due to some dependency conflicts/installation issues, we have for now reverted to a docker only build.
First, we need to setup obelisk. The following commands will (1) make sure docker is installed (2) set flags to make sure that the docker build script grabs the correct dependencies (these will NOT be installed on your local machine, only in the docker) (3) tell Obelisk what other options you want and (4) setup obelisk aliases. Please note that the aliases file will be modified on your local machine then mounted into docker.
source setup.sh --dev-setup --unitree --mujoco
Technically the --unitree flag is optional, but it is required to interface with the Unitree SDK. The --mujoco flag is needed to run simulations.
Sometimes we have found that .bash_aliases is a folder. For this to work, you will need to delete that and make sure that a single file is created.
If you have just installed docker for the first time, you may need to run
newgrp docker
Now, there are a few options. We suggest working with obelisk from within a dev container through an IDE. VSCode has good support for this and the Jetbrains IDEs have this feature in beta. If you take this (suggested) route, then you will want to open the the dev container in the IDE using the provided .devcontainer.
To build the development Docker container, run from the repo root:
docker compose -f docker/docker-compose.yml run --build obelisk
To enter the container without rebuilding or to join from a different terminal window, run
docker compose -f docker/docker-compose.yml run obelisk
If you are running on a machine with no Nvidia GPUs, you can instead run
docker compose -f docker/docker-compose-no-gpu.yml run --build obelisk
Either way, your repository root will be mounted into the container at the exact same file location, your username, user ID, and group ID will be shared with the container, and you can freely run sudo without supplying a password for any command.
Building and Running the ROS Stack
All of the following commands should be run from within the devcontainer.
We now need to activate obelisk. Assuming you installed the aliases, you can now run
obk
The first time this is run it also builds obelisk. This activation command sources all the relevant scripts (like ROS) so that the stack can be used without hassle.
You can also build everything with the terminal command:
obk-build
this will also be sure to build everything in the correct order.
To launch a ROS stack we can use the following commands.
In a seperate terminal, we can run a ROS stack with:
obk-launch config=<config file> device=<device>
Specifically, for the dummy examples this looks like:
obk-launch config=dummy_cpp.yaml device=onboard
All the documentation for the Obelisk terminal aliases can be found here.
C++ Code Structure
The C++ libraries in obelisk/cpp are built with CMake.
All obelisk C++ libraries are placed in obelisk/. Each library should have its own folder. Within that folder there should be an include folder, a CMakeLists.txt, and the source files (i.e., not the header files - those go in include).
Testing
Unit tests are managed with Catch2. Ultimately we plan to run the tests with CTest, and therefore all unit tests need to be registered with CTest, see here. The tests are all placed within tests/tests_cpp.