diff --git a/.dockerignore b/.dockerignore
index 214c85c2a..2304aa3b5 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -3,7 +3,6 @@
build
docs
install
-scripts
plugins
gui/controlpanel/node_modules
gui/controlpanel/package-lock.json
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index a676d591c..f692f08db 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -3,6 +3,8 @@ name: Docker Image CI
on:
push:
branches: [ "dev*" ]
+ pull_request:
+ branches: [ "dev" ]
jobs:
build_dockerImage:
diff --git a/Dockerfile b/Dockerfile
index 03b9320ba..a5dda86ad 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,85 +8,16 @@ FROM ${FROM_IMAGE} AS cacher
ENV DEBIAN_FRONTEND=noninteractive
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
-# Install system deps
-COPY dependencies.txt /tmp/dependencies.txt
-RUN apt update && apt install -y libpaho-mqtt-dev \
- $(cat /tmp/dependencies.txt | tr '\n' ' ')
-
-RUN pip install pyOpenSSL
-
+ENV ROS_DISTRO=${ROS_DISTRO}
+ENV REPO_DIR=/root/atos_git
+# NODE_VERSION is also specified in the install_atos.sh script
ENV NODE_VERSION=16.20.0
-RUN apt install -y curl
-RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
-ENV NVM_DIR=/root/.nvm
-RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
-RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
-RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
-RUN node --version
-RUN npm --version
-
-# Install ROS2 libs
-RUN \
- --mount=type=cache,target=/var/cache/apt \
- apt update && apt install -y \
- python3-colcon-common-extensions \
- ros-${ROS_DISTRO}-geographic-msgs \
- ros-${ROS_DISTRO}-geometry-msgs \
- ros-${ROS_DISTRO}-std-msgs \
- ros-${ROS_DISTRO}-std-srvs \
- ros-${ROS_DISTRO}-desktop \
- ros-${ROS_DISTRO}-nav-msgs \
- ros-${ROS_DISTRO}-geographic-msgs \
- ros-${ROS_DISTRO}-foxglove-msgs \
- ros-${ROS_DISTRO}-pcl-conversions \
- ros-${ROS_DISTRO}-rosbridge-suite
-
-
-ENV TEMP_SRC_PATH=/root/sourceinstall
-RUN mkdir -p $TEMP_SRC_PATH
-WORKDIR /root/sourceinstall
-# Install OpenSimulationInterface
-RUN cd $TEMP_SRC_PATH && \
- git clone https://github.com/OpenSimulationInterface/open-simulation-interface.git -b v3.4.0 && \
- cd open-simulation-interface && \
- mkdir -p build && cd build && \
- cmake .. && make -j4 && \
- sudo make install && \
- sudo sh -c "echo '/usr/local/lib/osi3' > /etc/ld.so.conf.d/osi3.conf" && \
- sudo ldconfig && \
- sudo rm -rf $TEMP_SRC_PATH/open-simulation-interface
-
-# Install esmini
-RUN cd $TEMP_SRC_PATH && \
- git clone https://github.com/esmini/esmini && \
- cd esmini && \
- mkdir -p build && cd build && \
- cmake .. && make -j4 && \
- sudo make install && \
- sudo cp ../bin/libesminiLib.so /usr/local/lib && \
- sudo cp ../bin/libesminiRMLib.so /usr/local/lib && \
- sudo mkdir -p /usr/local/include/esmini/ && \
- sudo cp ../EnvironmentSimulator/Libraries/esminiLib/esminiLib.hpp /usr/local/include/esmini/ && \
- sudo cp ../EnvironmentSimulator/Libraries/esminiRMLib/esminiRMLib.hpp /usr/local/include/esmini/ && \
- sudo ldconfig && \
- sudo rm -rf $TEMP_SRC_PATH/esmini
-
-
-
-WORKDIR /root/atos_ws
-# Setup workspace (.dockerignore is used to avoid copying unnecessary files)
-RUN mkdir -p ./src/atos
-COPY . ./src/atos
-RUN mv ./src/atos/atos_interfaces ./src
-
-# Build
-RUN . /opt/ros/${ROS_DISTRO}/setup.sh && \
- MAKEFLAGS=-j4 colcon build && \
- chmod +x /root/atos_ws/install/setup.sh && \
- rm -rf /root/atos_ws/build /root/atos_ws/src
-
-RUN mkdir -p /root/.astazero/ATOS
-COPY ./conf /root/.astazero/ATOS/
-
-RUN echo "source /root/atos_ws/install/setup.sh" >> /root/.bashrc
\ No newline at end of file
+SHELL ["/bin/bash", "-c"]
+
+WORKDIR /root/atos_git
+COPY ./scripts/ ./scripts
+RUN --mount=type=cache,target=/var/cache/apt \
+ ./scripts/install_deps.sh ${REPO_DIR}
+COPY . .
+RUN ./scripts/install_atos.sh ${REPO_DIR}
\ No newline at end of file
diff --git a/docs/Installation/installation.md b/docs/Installation/installation.md
index 185e56649..697605939 100644
--- a/docs/Installation/installation.md
+++ b/docs/Installation/installation.md
@@ -1,5 +1,5 @@
# Instructions
-There are two ways of starting ATOS: using the docker image or building from source. The docker image is the easiest way to get started, but if you intend to make changes to ATOS, we recommend building from source.
+There are two ways of starting ATOS: using the docker image or building from source. The docker image is the easiest way to get started, but if you intend to make changes to ATOS, we recommend building from source with the setup_atos.sh script.
## Using the docker image
To run ATOS using docker compose, first [install docker](https://docs.docker.com/engine/install/) on your computer. Download the [ATOS repo](https://github.com/RI-SE/ATOS). Then, run the following command from the root repo directory:
@@ -23,9 +23,9 @@ sudo chown -R $USER:$USER ~/.astazero/ATOS/
```
## Using the installation script
-ATOS comes with an installation script that automates the installation process. It is intended for use on Ubuntu 20.04 or 22.04, and has been tested on a fresh install of Ubuntu 20.04. The script will install ROS 2, ATOS dependencies, and ATOS itself. It will also create a workspace and build ATOS. The script can be executed using the following command:
+ATOS comes with an installation script that automates the installation process. It is intended for use on Ubuntu 20.04 or 22.04, and has been tested on a fresh install of Ubuntu 22.04. The script will install ROS 2, ATOS dependencies, and ATOS itself. It will also create a workspace and build ATOS. The script can be executed using the following command:
```bash
-./install_atos.sh
+./setup_atos.sh
```
## Building from source manually
diff --git a/install_atos.sh b/install_atos.sh
deleted file mode 100755
index 52fcd6dcb..000000000
--- a/install_atos.sh
+++ /dev/null
@@ -1,302 +0,0 @@
-#!/bin/bash
-
-#####################################
-###### Pre-installation checks ######
-#####################################
-
-# Get the script location
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
-
-# Function to get Ubuntu distribution codename
-get_ubuntu_codename() {
- source /etc/os-release
- echo $UBUNTU_CODENAME
-}
-
-# Function that checks if command failed
-check_command_failed() {
- local exitcode="$1"
- local error_message="$2"
-
- if [ $exitcode -ne 0 ]; then
- echo "$error_message"
- exit 1
- fi
-}
-
-# Check if running on Ubuntu
-if ! grep -q "Ubuntu" /etc/os-release; then
- echo "This script is designed for Ubuntu systems only."
- exit 1
-fi
-
-# Set ROS_DISTRO based on Ubuntu distribution
-case "$(get_ubuntu_codename)" in
- "focal")
- ROS_DISTRO=foxy
- ;;
- "jammy")
- ROS_DISTRO=humble
- ;;
- *)
- echo "Unsupported Ubuntu distribution. Only 20.04 (focal) and 22.04 (jammy) are supported."
- exit 1
- ;;
-esac
-
-# Prompt user to acknowledge installation
-echo "This script will try to install all necessary dependencies for ATOS. Please open and inspect this script for further details."
-echo "ROS distribution: $ROS_DISTRO"
-read -p "Do you wish to continue? [Y/n] " -n 1 -r
-echo
-if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
-fi
-
-# Check internet connection
-if ! ping -q -c 1 -W 1 google.com >/dev/null; then
- echo "No internet connection detected. Please connect to the internet and try again."
- exit 1
-fi
-
-#######################################
-###### Install ATOS dependencies ######
-#######################################
-
-# Update and install required dependencies specified in dependencies.txt file
-apt_deps=$(cat dependencies.txt | tr '\n' ' ')
-echo "Installing dependencies... $apt_deps"
-sudo apt update && sudo apt install -y ${apt_deps}
-
-# Check if apt failed to install dependencies
-check_command_failed $? "Failed to install dependencies."
-
-################################################
-###### Install Control Panel dependencies ######
-################################################
-
-echo "Installing nvm and Node.js..."
-if [ "$ROS_DISTRO" == "humble" ]; then
- NODE_VERSION=16.20.0
-elif [ "$ROS_DISTRO" == "foxy" ]; then
- NODE_VERSION=12
-fi
-NVM_DIR="$HOME/.nvm"
-
-if ! command -v nvm &> /dev/null; then
- echo "nvm not found, installing..."
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
- . "$NVM_DIR/nvm.sh"
- check_command_failed $? "Failed to install nvm."
-else
- echo "nvm already installed, skipping installation..."
-fi
-
-echo "Installing Node.js v${NODE_VERSION}..."
-nvm install ${NODE_VERSION}
-nvm use v${NODE_VERSION}
-nvm alias default v${NODE_VERSION}
-echo 'export PATH="$HOME/.nvm/versions/node/v${NODE_VERSION}/bin/:$PATH"' >> $HOME/.bashrc
-source $HOME/.bashrc
-
-# Install pyOpenSSL
-pip install pyOpenSSL
-
-#######################################
-###### Install ROS2 dependencies ######
-#######################################
-
-# Check if the ROS2 repository is already added
-if ! (dpkg -l | grep -q "ros-$ROS_DISTRO-desktop"); then
- echo "Adding the ROS2 $ROS_DISTRO apt repository..."
-
- # Install ROS2 prerequisites
- sudo apt update && sudo apt install curl gnupg2 lsb-release
-
- # Authorize the ROS2 gpg key with apt
- sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
- -o /usr/share/keyrings/ros-archive-keyring.gpg
-
- # Add the ROS2 repo to sources list
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
-else
- echo "ROS2 $ROS_DISTRO" repository already added, skipping addition...
-fi
-
-# Install ROS2 packages
-echo "Installing ROS2 packages..."
-sudo apt install -y \
- ros-${ROS_DISTRO}-desktop \
- ros-${ROS_DISTRO}-geographic-msgs \
- ros-${ROS_DISTRO}-geometry-msgs \
- ros-${ROS_DISTRO}-std-msgs \
- ros-${ROS_DISTRO}-std-srvs \
- ros-${ROS_DISTRO}-nav-msgs \
- ros-${ROS_DISTRO}-geographic-msgs \
- ros-${ROS_DISTRO}-foxglove-msgs \
- ros-${ROS_DISTRO}-pcl-conversions \
- ros-${ROS_DISTRO}-rosbridge-suite
-check_command_failed $? "Failed to install ROS2 packages."
-
-if [ "$ROS_DISTRO" == "humble" ]; then
- sudo apt install -y libpaho-mqtt-dev
-elif [ "$ROS_DISTRO" == "foxy" ]; then
- sudo apt install -y ros-foxy-paho-mqtt-c
-fi
-
-###########################################
-###### Install some deps from source ######
-###########################################
-
-# Set custom path for source installation, first check if it exists
-SOURCE_PATH=~/temp/atos_install
-if [ -d "$SOURCE_PATH" ]; then
- echo "Removing preexisting path ${SOURCE_PATH} for source installation..."
- sudo rm -rf $SOURCE_PATH
-fi
-
-echo "Creating custom path for source installation at $SOURCE_PATH"
-mkdir -p $SOURCE_PATH
-
-# Install OpenSimulationInterface but first check if the library is already installed
-if [ -d "/usr/local/lib/osi3" ]; then
- echo "OpenSimulationInterface already installed, skipping installation..."
-else
- echo "Installing OpenSimulationInterface..."
- git clone https://github.com/OpenSimulationInterface/open-simulation-interface.git -b v3.4.0 $SOURCE_PATH/open-simulation-interface
- cd $SOURCE_PATH/open-simulation-interface
- mkdir -p build && cd build
- cmake .. && make
- check_command_failed $? "Failed to build OpenSimulationInterface."
- sudo make install
- check_command_failed $? "Failed to install OpenSimulationInterface."
- sudo sh -c "echo '/usr/local/lib/osi3' > /etc/ld.so.conf.d/osi3.conf"
- sudo ldconfig
- check_command_failed $? "Failed ldconfig after installing OpenSimulationInterface."
-fi
-
-# Install esmini but first check if the library is already installed
-if [ -d "/usr/local/include/esmini" ]; then
- echo "esmini already installed, skipping installation..."
-else
- echo "Installing esmini..."
- git clone https://github.com/esmini/esmini.git $SOURCE_PATH/esmini
- cd $SOURCE_PATH/esmini
- mkdir -p build && cd build
- cmake .. && make
- check_command_failed $? "Failed to build esmini."
- sudo make install
- check_command_failed $? "Failed to install esmini."
- sudo cp ../bin/libesminiLib.so /usr/local/lib
- sudo cp ../bin/libesminiRMLib.so /usr/local/lib
- sudo mkdir -p /usr/local/include/esmini/
- sudo cp ../EnvironmentSimulator/Libraries/esminiLib/esminiLib.hpp /usr/local/include/esmini/
- sudo cp ../EnvironmentSimulator/Libraries/esminiRMLib/esminiRMLib.hpp /usr/local/include/esmini
- sudo ldconfig
- check_command_failed $? "Failed ldconfig after installing esmini."
-fi
-
-# Remove custom path for source installation
-echo "Removing custom path for source installation..."
-sudo rm -rf $SOURCE_PATH
-check_command_failed $? "Failed to remove ${$SOURCE_PATH} path for source installation."
-
-########################################
-###### Start installation of ATOS ######
-########################################
-
-echo "Installing ATOS..."
-# Create a workspace dir if it doesn't exist
-if [ ! -d "~/atos_ws/src" ]; then
- mkdir -p ~/atos_ws/src
-fi
-cd ~/atos_ws
-
-# Set ATOS_PATH to the script location
-ATOS_PATH="$SCRIPT_DIR"
-
-# Set ATOS_INTERFACES_PATH using ATOS_PATH
-ATOS_INTERFACES_PATH="$ATOS_PATH/atos_interfaces"
-
-# Function to update symlink if it doesn't point to the correct location
-update_symlink() {
- local target="$1"
- local link_name="$2"
-
- if [ -L "$link_name" ]; then
- current_target="$(readlink "$link_name")"
- if [ "$current_target" != "$target" ]; then
- rm "$link_name"
- ln -s "$target" "$link_name"
- echo "Updated symlink $link_name to $target because it pointed to $current_target previously."
- fi
- else
- ln -s "$target" "$link_name"
- echo "Created symlink $link_name to $target"
- fi
-}
-# Update symlinks to atos and atos_interfaces
-update_symlink "$ATOS_PATH" ~/atos_ws/src/atos
-update_symlink "$ATOS_INTERFACES_PATH" ~/atos_ws/src/atos_interfaces
-
-
-# Change directory into the workspace and build, check with the user before continuing
-echo "Dependecy installation done and ATOS workspace created."
-read -p "Do you wish to continue by installing ATOS with colcon? [Y/n] " -n 1 -r
-echo
-if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
-fi
-
-# First make sure the submodules are up to date
-echo "Updating submodules to make sure they are up to date..."
-cd ~/atos_ws/src/atos
-git submodule update --init --recursive
-cd -
-
-# temporarily cd into the workspace and build with colcon
-echo "Building ATOS..."
-cd ~/atos_ws
-MAKEFLAGS=-j8 && colcon build --symlink-install
-check_command_failed $? "Failed to build ATOS."
-cd -
-
-#####################################
-###### Configure setup scripts ######
-#####################################
-
-# Function to add the setup.bash source line if it doesn't exist
-add_source_line_if_needed() {
- local file="$1"
- local shell_type="$2"
- local source_line="$3$shell_type"
-
- if ! grep -qF "$source_line" "$file"; then
- echo "Adding the following line to your shells config file: $file"
- echo "$source_line"
- echo "$source_line" >> "$file"
- fi
-}
-
-atos_setup_script="source ~/atos_ws/install/setup."
-ros2_setup_script="source /opt/ros/$ROS_DISTRO/setup."
-
-case "$SHELL" in
- */bash)
- add_source_line_if_needed ~/.bashrc "bash" "${atos_setup_script}"
- add_source_line_if_needed ~/.bashrc "bash" "${ros2_setup_script}"
- source $HOME/.bashrc
- ;;
- */zsh)
- add_source_line_if_needed ~/.zshrc "zsh" "${atos_setup_script}"
- add_source_line_if_needed ~/.zshrc "zsh" "${ros2_setup_script}"
- source $HOME/.zshrc
- ;;
- *)
- echo "Unsupported shell detected! Please use either bash or zsh shells to run ATOS"
- exit 1
- ;;
-esac
-
-echo "ATOS installation and setup is complete. You can now test run ATOS by running the following command:"
-echo "ros2 launch atos launch_basic.py"
diff --git a/scripts/dependencies.txt b/scripts/dependencies.txt
new file mode 100644
index 000000000..90c8a7d1a
--- /dev/null
+++ b/scripts/dependencies.txt
@@ -0,0 +1,13 @@
+ curl
+ wget
+ unzip
+ libsystemd-dev
+ libprotobuf-dev
+ libpaho-mqtt-dev
+ protobuf-compiler
+ libeigen3-dev
+ nlohmann-json3-dev
+ gnupg2
+ lsb-release
+ python3-pip
+ proj-bin
\ No newline at end of file
diff --git a/scripts/install_atos.sh b/scripts/install_atos.sh
new file mode 100755
index 000000000..0ae64a2ea
--- /dev/null
+++ b/scripts/install_atos.sh
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+
+# Check if called without arguments
+if [ $# -eq 0 ]; then
+ echo "Don't call this file directly, use setup_atos.sh instead."
+ echo "Usage: ./install_deps.sh "
+ exit 0
+fi
+
+# Take the first argument as the PATH to the ATOS git repo
+ATOS_REPO_PATH="$1"
+source "${ATOS_REPO_PATH}/scripts/install_functions.sh"
+check_command_failed $? "Failed to source ${ATOS_REPO_PATH}/scripts/install_functions.sh"
+
+################################################
+###### Install Control Panel dependencies ######
+################################################
+
+echo "Installing nvm and Node.js..."
+NODE_VERSION=16.20.0 # Also specified in the Dockerfile
+NVM_DIR="$HOME/.nvm"
+
+if ! command -v nvm &> /dev/null; then
+ echo "nvm not found, installing..."
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
+ . "$NVM_DIR/nvm.sh"
+ check_command_failed $? "Failed to install nvm."
+else
+ echo "nvm already installed, skipping installation..."
+fi
+
+echo "Installing Node.js v${NODE_VERSION}..."
+nvm install ${NODE_VERSION}
+nvm use v${NODE_VERSION}
+nvm alias default v${NODE_VERSION}
+echo 'export PATH="$HOME/.nvm/versions/node/v${NODE_VERSION}/bin/:$PATH"' >> $HOME/.bashrc
+source $HOME/.bashrc
+npm --version
+
+# Install pyOpenSSL
+pip install pyOpenSSL
+
+################################################
+############## Install ATOS ####################
+################################################
+
+# Create a workspace dir if it doesn't exist
+if [ ! -d "$HOME/atos_ws/src" ]; then
+ mkdir -p $HOME/atos_ws/src
+fi
+cd $HOME/atos_ws
+
+# Set ATOS_INTERFACES_PATH using ATOS_PATH
+ATOS_INTERFACES_PATH="$ATOS_REPO_PATH/atos_interfaces"
+
+# Update symlinks to atos and atos_interfaces
+update_symlink "$ATOS_REPO_PATH" $HOME/atos_ws/src/atos
+update_symlink "$ATOS_INTERFACES_PATH" $HOME/atos_ws/src/atos_interfaces
+
+
+# Change directory into the workspace and build, check with the user before continuing
+echo "Dependecy installation done and ATOS workspace created."
+
+# First make sure the submodules are up to date
+echo "Updating submodules to make sure they are up to date..."
+cd $HOME/atos_ws/src/atos
+git submodule update --init --recursive
+cd -
+
+# temporarily cd into the workspace and build with colcon
+echo "Building ATOS..."
+cd $HOME/atos_ws
+source /opt/ros/$ROS_DISTRO/setup.bash
+MAKEFLAGS=-j4 colcon build --symlink-install
+check_command_failed $? "Failed to build ATOS."
+cd -
+
+#####################################
+###### Configure setup scripts ######
+#####################################
+
+atos_setup_script="source $HOME/atos_ws/install/setup."
+ros2_setup_script="source /opt/ros/$ROS_DISTRO/setup."
+
+case "$SHELL" in
+ */bash)
+ add_source_line_if_needed $HOME/.bashrc "bash" "${atos_setup_script}"
+ add_source_line_if_needed $HOME/.bashrc "bash" "${ros2_setup_script}"
+ source $HOME/.bashrc
+ ;;
+ */zsh)
+ add_source_line_if_needed $HOME/.zshrc "zsh" "${atos_setup_script}"
+ add_source_line_if_needed $HOME/.zshrc "zsh" "${ros2_setup_script}"
+ source $HOME/.zshrc
+ ;;
+ *)
+ echo "Unsupported shell detected! Please use either bash or zsh shells to run ATOS"
+ exit 1
+ ;;
+esac
\ No newline at end of file
diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh
new file mode 100755
index 000000000..8708cc27c
--- /dev/null
+++ b/scripts/install_deps.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+# Check if called without arguments
+if [ $# -eq 0 ]; then
+ echo "Don't call this file directly, use setup_atos.sh instead."
+ echo "Usage: ./install_deps.sh "
+ exit 0
+fi
+# Take the first argument as the PATH to the ATOS git repo
+ATOS_REPO_PATH="$1"
+#fail unless var is set
+source "${ATOS_REPO_PATH}/scripts/install_functions.sh"
+
+# Update and install required dependencies specified in dependencies.txt file
+apt_deps=$(cat ${ATOS_REPO_PATH}/scripts/dependencies.txt | tr '\n' ' ')
+echo "Installing dependencies... $apt_deps"
+sudo apt update && sudo apt install -y ${apt_deps}
+
+# Check if apt failed to install dependencies
+check_command_failed $? "Failed to install dependencies."
+
+#######################################
+###### Install ROS2 dependencies ######
+#######################################
+ROS_DISTRO=humble
+
+# Check if the ROS2 repository is already added
+if ! (dpkg -l | grep -q "ros-$ROS_DISTRO-desktop"); then
+ echo "Adding the ROS2 $ROS_DISTRO apt repository..."
+
+ # Install ROS2 prerequisites
+ sudo apt update && sudo apt install -y lsb-release ros-dev-tools
+
+ # Authorize the ROS2 gpg key with apt
+ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
+ -o /usr/share/keyrings/ros-archive-keyring.gpg
+
+ # Add the ROS2 repo to sources list
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
+else
+ echo "ROS2 $ROS_DISTRO" repository already added, skipping addition...
+fi
+
+# Install ROS2 packages
+echo "Installing ROS2 packages..."
+sudo apt install -y \
+ ros-${ROS_DISTRO}-desktop \
+ ros-${ROS_DISTRO}-geographic-msgs \
+ ros-${ROS_DISTRO}-geometry-msgs \
+ ros-${ROS_DISTRO}-std-msgs \
+ ros-${ROS_DISTRO}-std-srvs \
+ ros-${ROS_DISTRO}-nav-msgs \
+ ros-${ROS_DISTRO}-geographic-msgs \
+ ros-${ROS_DISTRO}-foxglove-msgs \
+ ros-${ROS_DISTRO}-pcl-conversions \
+ ros-${ROS_DISTRO}-rosbridge-suite
+check_command_failed $? "Failed to install ROS2 packages."
+
+###########################################
+###### Install some deps from source ######
+###########################################
+
+# Set custom path for source installation, first check if it exists
+SOURCE_PATH=$HOME/temp/atos_install
+if [ -d "$SOURCE_PATH" ]; then
+ echo "Removing preexisting path ${SOURCE_PATH} for source installation..."
+ sudo rm -rf $SOURCE_PATH
+fi
+
+echo "Creating custom path for source installation at $SOURCE_PATH"
+mkdir -p $SOURCE_PATH
+
+# Install OpenSimulationInterface but first check if the library is already installed
+if [ -d "/usr/local/lib/osi3" ]; then
+ echo "OpenSimulationInterface already installed, skipping installation..."
+else
+ echo "Installing OpenSimulationInterface..."
+ git clone --depth 1 --branch v3.4.0 https://github.com/OpenSimulationInterface/open-simulation-interface.git $SOURCE_PATH/open-simulation-interface
+ cd $SOURCE_PATH/open-simulation-interface
+ mkdir -p build && cd build
+ cmake .. && make -j8
+ check_command_failed $? "Failed to build OpenSimulationInterface."
+ sudo make install
+ check_command_failed $? "Failed to install OpenSimulationInterface."
+ sudo sh -c "echo '/usr/local/lib/osi3' > /etc/ld.so.conf.d/osi3.conf"
+ sudo ldconfig
+ check_command_failed $? "Failed ldconfig after installing OpenSimulationInterface."
+fi
+
+# Install esmini but first check if the library is already installed
+if [ -d "/usr/local/include/esmini" ]; then
+ echo "esmini already installed, skipping installation..."
+else
+ echo "Downloading esmini binaries..."
+ wget https://github.com/esmini/esmini/releases/download/v2.32.0/esmini-bin_Linux.zip -O $SOURCE_PATH/esmini-bin_Linux.zip
+ check_command_failed $? "Failed to get esmini."
+ unzip $SOURCE_PATH/esmini-bin_Linux.zip -d $SOURCE_PATH/esmini-bin_Linux
+ cd $SOURCE_PATH/esmini-bin_Linux
+ sudo cp esmini/bin/libesminiLib.so /usr/local/lib
+ sudo cp esmini/bin/libesminiRMLib.so /usr/local/lib
+ sudo mkdir -p /usr/local/include/esmini/
+ sudo cp esmini/EnvironmentSimulator/Libraries/esminiLib/esminiLib.hpp /usr/local/include/esmini/
+ sudo cp esmini/EnvironmentSimulator/Libraries/esminiRMLib/esminiRMLib.hpp /usr/local/include/esmini
+ sudo ldconfig
+ check_command_failed $? "Failed ldconfig after installing esmini."
+fi
+
+# Remove custom path for source installation
+echo "Removing custom path for source installation..."
+sudo rm -rf $SOURCE_PATH
+check_command_failed $? "Failed to remove ${SOURCE_PATH} path for source installation."
\ No newline at end of file
diff --git a/scripts/install_functions.sh b/scripts/install_functions.sh
new file mode 100755
index 000000000..d9fd37a1c
--- /dev/null
+++ b/scripts/install_functions.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+# Function to get Ubuntu distribution codename
+get_ubuntu_codename() {
+ source /etc/os-release
+ echo $UBUNTU_CODENAME
+}
+
+# Function that checks if command failed
+check_command_failed() {
+ local exitcode="$1"
+ local error_message="$2"
+
+ if [ $exitcode -ne 0 ]; then
+ echo "$error_message"
+ exit 1
+ fi
+}
+
+# Function to update symlink if it doesn't point to the correct location
+update_symlink() {
+ local target="$1"
+ local link_name="$2"
+
+ if [ -L "$link_name" ]; then
+ current_target="$(readlink "$link_name")"
+ if [ "$current_target" != "$target" ]; then
+ rm "$link_name"
+ ln -s "$target" "$link_name"
+ echo "Updated symlink $link_name to $target because it pointed to $current_target previously."
+ fi
+ else
+ ln -s "$target" "$link_name"
+ echo "Created symlink $link_name to $target"
+ fi
+}
+
+# Function to add the setup.bash source line if it doesn't exist
+add_source_line_if_needed() {
+ local file="$1"
+ local shell_type="$2"
+ local source_line="$3$shell_type"
+
+ if ! grep -qF "$source_line" "$file"; then
+ echo "Adding the following line to your shells config file: $file"
+ echo "$source_line"
+ echo "# Line below added by ATOS setup script" >> "$file"
+ echo "$source_line" >> "$file"
+ fi
+}
\ No newline at end of file
diff --git a/setup_atos.sh b/setup_atos.sh
new file mode 100755
index 000000000..7b2d0e260
--- /dev/null
+++ b/setup_atos.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+#####################################
+###### Pre-installation checks ######
+#####################################
+
+source "scripts/install_functions.sh"
+
+# Get this file location
+REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
+
+# Check if running on Ubuntu
+if ! grep -q "Ubuntu" /etc/os-release; then
+ echo "This script is designed for Ubuntu systems only."
+ exit 1
+fi
+
+# Set ROS_DISTRO based on Ubuntu distribution
+case "$(get_ubuntu_codename)" in
+ "focal")
+ ;;
+ "jammy")
+ ;;
+ *)
+ echo "Unsupported Ubuntu distribution. Only 20.04 (focal) and 22.04 (jammy) are supported."
+ exit 1
+ ;;
+esac
+
+# Add -h/--help option
+if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
+ echo "Usage: ./setup_atos.sh [single option]"
+ echo "This script will install all necessary dependencies, setup the ROS workspace at ~/atos_ws and install ATOS. Please open and inspect this script for further details."
+ #Show options
+ echo "Options:"
+ echo " -h, --help Show this help message and exit"
+ echo " -d Only install dependencies"
+ exit 0
+
+# Only install dependencies
+elif [ "$1" == "-d" ]; then
+ INSTALL_ATOS=false
+else
+ INSTALL_ATOS=true
+fi
+
+#######################################
+###### Install ATOS dependencies ######
+#######################################
+echo "Installing ATOS dependencies..."
+${REPO_DIR}/scripts/install_deps.sh ${REPO_DIR}
+
+if [ $? -ne 0 ]; then
+ echo "Failed to install dependencies."
+ exit 1
+fi
+########################################
+###### Start installation of ATOS ######
+########################################
+if [ "$INSTALL_ATOS" = false ]; then
+ echo "ATOS installation skipped."
+ exit 0
+fi
+echo "Installing ATOS..."
+${REPO_DIR}/scripts/install_atos.sh ${REPO_DIR}
+
+if [ $? -ne 0 ]; then
+ echo "Failed to install ATOS."
+ exit 1
+fi
+
+echo "ATOS installation and setup is complete. You can now test run ATOS by running the following command:"
+echo "ros2 launch atos launch_basic.py"
+echo "Please see the documentation for further details: https://atos.readthedocs.io/en/latest/"