Skip to content

Commit

Permalink
Enable auto launch of isaac and airstack via tmux in docker (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewjong authored Oct 24, 2024
1 parent c3bed17 commit 86a19c1
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 77 deletions.
1 change: 1 addition & 0 deletions docker/Dockerfile.airstack-dev
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ RUN apt install -y \
cmake build-essential \
less htop jq \
python3-pip \
tmux \
gdb

# Package dependencies
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile.isaac-ros
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RUN apt-get update && apt-get install -q -y --no-install-recommends \
dirmngr \
gnupg2 \
unzip \
tmux \
&& rm -rf /var/lib/apt/lists/*

# setup keys
Expand Down
29 changes: 24 additions & 5 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
services:
# ==============================================================================
isaac-sim:
image: &isaac-sim-image airlab-storage.andrew.cmu.edu:5001/shared/isaac-sim_ros-humble:v1.0.0
image: &isaac-sim-image airlab-storage.andrew.cmu.edu:5001/shared/isaac-sim_ros-humble:v1.0.1
build:
context: ../
dockerfile: docker/Dockerfile.isaac-ros
tags:
- *isaac-sim-image
container_name: isaac-sim
entrypoint: bash
entrypoint: "" # override the default entrypoint with nothing
# for some reason the tmux session manager only works when isaac is running in tmux
command: >
bash -c "
tmux new -d -s isaac
&& tmux send-keys -t isaac 'runapp' ENTER
&& sleep infinity"
# Interactive shell
stdin_open: true # docker run -i
tty: true # docker run -t
Expand Down Expand Up @@ -59,13 +65,19 @@ services:

# ==============================================================================
robot:
image: &airstack-dev-image airlab-storage.andrew.cmu.edu:5001/shared/airstack-dev:v0.5.2
image: &airstack-dev-image airlab-storage.andrew.cmu.edu:5001/shared/airstack-dev:v0.5.3
build:
context: ../
dockerfile: docker/Dockerfile.airstack-dev
tags:
- *airstack-dev-image
entrypoint: bash -c "service ssh restart && bash"
entrypoint: ""
# we use tmux send-keys so that the session stays alive
command: >
bash -c "ssh service restart;
tmux new -d -s robot_bringup
&& tmux send-keys -t robot_bringup 'ros2 launch robot_bringup robot.launch.xml' ENTER
&& sleep infinity"
# Interactive shell
stdin_open: true # docker run -i
tty: true # docker run -t
Expand Down Expand Up @@ -102,13 +114,20 @@ services:
ground-control-station:
image: *airstack-dev-image
container_name: ground-control-station
entrypoint: bash -c "service ssh restart && bash"
entrypoint: ""
command: >
bash -c "ssh service restart;
tmux new -d -s gcs_bringup
&& tmux send-keys -t gcs_bringup 'ros2 launch gcs_bringup gcs.launch.xml' ENTER
&& sleep infinity"
# Interactive shell
stdin_open: true # docker run -i
tty: true # docker run -t
# Needed to display graphical applications
ipc: host
privileged: true
networks:
- airstack_network
environment:
- DISPLAY
- QT_X11_NO_MITSHM=1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ def kill_all_ascent_sessions():
sessions.append(line.split(':')[0])

for session in sessions:
subprocess.call('tmux kill-session -t ' + session, shell=True)
if session.startswith(AscentSitlLaunchTool.get_tmux_session_prefix()):
subprocess.call('tmux kill-session -t ' + session, shell=True)

def get_dronekit_address(self):
return '127.0.0.1:' + str(self.isaac_sim_port)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def refresh_tmux_sessions(self):
def get_attach(session_name):
def attach():
#print('xterm -e "tmux a -t ' + session_name + '"')
subprocess.Popen('xterm -e "tmux a -t \\"' + session_name + '\\""', shell=True)
subprocess.Popen('xterm -bg black -fg white -e "tmux a -t \\"' + session_name + '\\""', shell=True)
return attach

def get_kill(session_name):
Expand Down
6 changes: 3 additions & 3 deletions docker/isaac-sim/.bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

# don't put duplicate lines in the history. See bash(1) for more options
# ... or force ignoredups and ignorespace
HISTCONTROL=ignoredups:ignorespace
Expand Down Expand Up @@ -88,6 +85,9 @@ alias l='ls -CF'
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

# make xterm black bg
alias xterm='xterm -bg black -fg white'

alias emacs='emacs -nw'
alias sis='source install/setup.bash'

Expand Down
49 changes: 32 additions & 17 deletions docs/development/docker_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ AirStack is designed for multi-robot development, and is setup to run multiple r

To mimic interacting with real world robots, we use Docker Compose to manage Docker containers that isolate the simulation, each robot, and the ground control station.


The details of the docker compose setup is in `AirStack/docker/docker-compose.yaml`.

In essence, the compose file launches:
Expand All @@ -13,36 +12,39 @@ In essence, the compose file launches:
- ground control station
- robots

all get created on the same default Docker bridge network.
all get created on the same default Docker bridge network.
This lets them communicate with ROS2 on the same network.


Each robot has its own ROS_DOMAIN_ID.

## Pull Images

To use the AirLab docker registry:

```bash
cd AirStack/docker/
docker login airlab-storage.andrew.cmu.edu:5001
## <Enter your andrew id (without @andrew.cmu.edu)>
## <Enter your andrew password>

## Pull the images in the docker compose file
docker compose pull
docker compose pull
```

Catelog: [AirLab Registry Images](https://airlab-storage.andrew.cmu.edu:5001/v2/_catalog).

Available image tags:
Available image tags:
[airstack-dev](https://airlab-storage.andrew.cmu.edu:5001/v2/shared/airstack-dev/tags/list),
[isaac-sim_ros-humble](https://airlab-storage.andrew.cmu.edu:5001/v2/shared/isaac-sim_ros-humble/tags/list)

## Build Images

```bash
docker compose build
```

## Start and Stop
## Start, Stop, and Remove

Start
```bash
docker compose up -d --scale robot=[NUM_ROBOTS]
Expand All @@ -53,11 +55,16 @@ docker ps -a

Stop
```bash
docker compose down
docker compose stop
```

Remove
```bash
docker compose down
```

## SSH into Robots

The containers mimic the robots' onboard computers on the same network. Therefore we intend to interface with the robots through ssh.

The `ground-control-station` and `docker-robot-*` containers are setup with ssh daemon, so you can ssh into the containers using the IP address.
Expand All @@ -67,14 +74,15 @@ You can get the IP address of each container by running the following command:
```bash
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [CONTAINER-NAME]
```

Then ssh in, for example:

```bash
ssh [email protected]
```

The ssh password is `airstack`.


## Container Details

```mermaid
Expand All @@ -91,25 +99,30 @@ graph TD
```


### Isaac Sim

Start a bash shell in the Isaac Sim container:

```bash
docker exec -it isaac-sim bash
# if the isaac container is already running, execute a bash shell in it
docker compose exec isaac-sim bash
# or if not, start a new container
docker compose run isaac-sim bash
```


`runapp` launches Isaac Sim.
The alias `runapp` launches Isaac Sim.
The `--path` argument can be passed with a path to a `.usd` file to load a scene.

It can also be run in headless mode with `./runheadless.native.sh` to stream to [Omniverse Streaming Client](https://docs.omniverse.nvidia.com/streaming-client/latest/user-manual.html) or `./runheadless.webrtc.sh` to [stream to a web browser](https://docs.omniverse.nvidia.com/extensions/latest/ext_livestream/webrtc.html).

The container also has the isaacsim ROS2 package within that can be launched with `ros2 launch isaacsim run_isaacsim.launch.py`.
The container also has the isaacsim ROS2 package within that can be launched with `ros2 launch isaacsim run_isaacsim.launch.py`.

### Robot

Start a bash shell in a robot container, e.g. for robot_1:

```bash
docker exec -it docker-robot-1 bash
docker compose exec docker-robot-1 bash
```

```bash
Expand All @@ -118,21 +131,23 @@ cws # cleans workspace
bws # builds workspace
bws --packages-select [your_packages] # builds only desired packages
sws # sources workspace
ros2 launch robot_bringup robot.launch.xml # top-level launch
ros2 launch robot_bringup robot.launch.xml # top-level launch
```

These aliases are in the `~/.bashrc` file.

Each robot has `ROS_DOMAIN_ID` set to its ID number. `ROBOT_NAME` is set to `robot_$ROS_DOMAIN_ID`.

### Ground Control Station

Currently the ground control station uses the same image as the robot container. This may change in the future.

Start a bash shell in a robot container:

```bash
docker exec -it ground-control-station bash
docker compose exec ground-control-station bash
```

The commands are currently the same.

On the GCS `ROS_DOMAIN_ID` is set to 0.
On the GCS `ROS_DOMAIN_ID` is set to 0.
Loading

0 comments on commit 86a19c1

Please sign in to comment.