Getting Started – Using Obelisk in a Downstream Project
Obelisk is a suite of tools designed to make robotics development simpler. The centerpiece of Obelisk is ROS, which allows Obelisk to be extended and used in real-world robotics tasks.
There are two main options for using Obelisk: (1) use Obelisk from within a docker container, or (2) run Obelisk locally on your system. We strongly recommond option (1) as Obelisk requires a number of complex dependencies. If you choose to take option (2) then there could be installation issues and/or system clutter. Using option (1) also makes your code less suscepitble to issues caused by adjusting your local machine’s configuraiton.
For developing the core Obelisk library, please see Development.
Setting up Obelisk with Docker
The key idea with using Docker is to make installation/setup easier and repeatable on everyone’s computer. There are a number of dependencies, especially ROS related, that have been known to cause issues when installed without any careful planning. By using a docker container we can mitigate these issues. That being said, ideally this Docker is just for Obelisk deployment. The ideal setup has your algorithm code as a seperate library, not dependent on ROS, which can then be added to this docker container. This also helps seperate code relating to running a robot with the underlying algorithms.
The recommended docker folder structure for using Obelisk is:
docker/
├── .env
├── Dockerfile
├── docker-compose.yml
And optionally, if you are using a devcontainer:
.devcontainer/
├── gpu/
├── devcontainer.json
├── no_gpu/
├── devcontainer.json
with the .devcontainer folder at the time layer as the docker folder.
Sample Dockerfile
A sample Dockerfile is as follows:
# syntax=docker/dockerfile:1
# base image
FROM ubuntu:22.04 as base
SHELL ["/bin/bash", "-c"]
# username, uid, gid
ARG USER=user
ARG UID=1000
ARG GID=1000
ARG OBELISK_ROOT=/
ENV USER=$USER
ENV UID=$UID
ENV GID=$GID
ENV OBELISK_ROOT=$OBELISK_ROOT
# set timezone
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# basic dependencies from docker_setup.sh (up until sudo and below)
RUN apt-get update && apt-get install -y \
curl \
build-essential \
cmake \
clang-tools-12 \
nano \
vim \
git \
libeigen3-dev \
x11-apps \
locales \
iputils-ping \
evtest \
sudo && \
rm -rf /var/lib/apt/lists/* && \
locale-gen en_US.UTF-8
# create non-root user with sudo privileges for certain commands
RUN groupadd --gid $GID $USER && \
useradd --uid $UID --gid $GID -m $USER -d /home/${USER} --shell /usr/bin/bash && \
echo "${USER}:password" | chpasswd && \
usermod -aG sudo ${USER} && \
echo "%${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# switch to new user and workdir
USER ${UID}
RUN echo "Pulling Obelisk..."
# clone Obelisk into this docker image at the $OBELISK_ROOT path
RUN git clone -b main https://github.com/Caltech-AMBER/obelisk.git /home/${USER}/obelisk
ENV OBELISK_ROOT=/home/${USER}/obelisk
# Install other dependencies here...
# you must run the setup script from a directory where the user has permissions
# run docker setup script in Dockerfile
WORKDIR /home/${USER}
RUN source /home/${USER}/obelisk/setup.sh --downstream-setup --mujoco
WORKDIR /home/${USER}
This docker file installs a number of basic tools and pulls obelisk and installs it. Note that here we can choose a specific Obelisk version to install if desired using -b flag in the clone - for now we are just installing main.
The line
RUN source /home/${USER}/obelisk/setup.sh --downstream-setup --mujoco
is critical as this runs the Obelisk setup script within the docker container. It is possible that you may need Obelisk to be configured differently, and you can do that by adjusting those flags in the Dockerfile.
The flag options are:
Options:
--dev-setup Setup for development of Obelisk.
--downstream-setup Setup for downstream use of Obelisk - suggested to build this in a docker container.
Hardware options:
--zed Enables ZED SDK
--unitree Enables the unitree interfaces
Simulation options:
--mujoco Enables Mujoco simulation. For now, without this flag there will be no simulation of any type.
Other options:
--help Display this help message and exit
We only want to use --dev-setup if we are preparing to develop core obelisk features, and in that case we want to use the docker container that comes in the Obelisk repo. We can choose hardware interfaces to be installed with --unitree or --zed. When deploying on a robot, you may not want a simulation environment, so you can not pass --mujoco.
Sample docker-compose.yml
Below is a sample docker-compose.yml that assumes you want to use an Nvidia GPU with Obelisk.
services:
downstream_obk:
shm_size: '12gb'
build:
context: .
args:
USER: $USER
UID: $UID
GID: $GID
dockerfile: Dockerfile
network_mode: host
ipc: host
environment:
NVIDIA_DRIVER_CAPABILITIES: all
DISPLAY: $DISPLAY
USER: $USER
UID: $UID
GID: $GID
QT_X11_NO_MITSHM: 1
security_opt:
- seccomp=unconfined
cap_add:
- NET_ADMIN
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- $HOME/.Xauthority:$HOME/.Xauthority:rw
- $HOME/.bashrc:$HOME/.bashrc
- $HOME/.ssh:$HOME/.ssh
ports:
- 7007:7007
- 10000:10000
privileged: true
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [ gpu ]
working_dir: $ROBOT_RL_ROOT
stdin_open: true
tty: true
command: /bin/bash
Sample .env
USER=${USER:-$(id -un)}
UID=1000
GID=1000
You may need to adjust the UID of GID depending on the users in your computer, but in general this works for most people.
Sample devcontainer.json
This file can be used to create a devcontainer in Vscode, which is currently the suggested way of developing in docker containers.
{
"name": "Obelisk GPU Dev Container",
"dockerComposeFile": "../../docker/docker-compose.yml",
"service": "downstream_obk",
"workspaceFolder": "${localWorkspaceFolder}",
"shutdownAction": "stopCompose",
"customizations": {
"vscode": {
"extensions": [
"mutantdino.resourcemonitor",
"ms-azuretools.vscode-docker",
"nvidia.nsight-vscode-edition",
"ritwickdey.liveserver",
"ms-vscode.cmake-tools",
"ms-python.python",
"charliermarsh.ruff"
]
}
},
}
Creating the Docker Container
Now we can enter into the docker container (or even better, this can be setup as a dev container). Within this docker container we can handle all development that interfaces our algorithm with Obelisk.
Run
docker compose -f docker/docker-compose.yml run --build downstream_obk
to build the container from the terminal.
Or if you are using a devcontainer you can rebuild and enter the container from within the VScode extension.
Basic Obelisk Usage
From here on out we assume that Obelisk is installed and you are in the associated docker container and the Obelisk aliases have been installed.
Now we need to activate Obelisk:
obk
This command sources all the relevant files (like ROS) so that the entire stack is ready to use. The first time this command runs Obelisk is also built. You can see more about the aliases here.
To build obelisk any other time we use
obk-build
If you are using a stable version of Obelisk, you should only need to run this once. If there are any build issues in subsequent builds we suggest running obk-clean followed by obk-build to clear the build cache and rebuild.
Once Obelisk is activated and built we can run a basic example to make sure everything is working as expected.
obk-launch config=dummy_cpp.yaml device=onboard
At this point you should see a Mujoco simulation running.
obk-launch is an important alias that calls the obelisk launch file. Assuming your code conforms to Obelisk standards (discussing in a later section), an obk-launch command should be all you need to bring the full stack, including simulation/hardware.