├── resource └── tudelft_hackathon ├── dockerfiles ├── ignition │ ├── README.md │ ├── ignition-foxy │ │ ├── entrypoint.sh │ │ └── Dockerfile │ └── ignition-humble │ │ └── Dockerfile ├── ros1-2-ignition │ ├── ros2_ws │ │ ├── build.sh │ │ ├── ros1_bridge.sh │ │ └── src │ │ │ └── cpp_pubsub │ │ │ ├── package.xml │ │ │ ├── src │ │ │ └── subscriber_member_function.cpp │ │ │ └── CMakeLists.txt │ ├── ros1_ws │ │ └── src │ │ │ └── beginner_tutorials │ │ │ ├── launch │ │ │ └── talk.launch │ │ │ ├── package.xml │ │ │ ├── src │ │ │ └── talker.cpp │ │ │ └── CMakeLists.txt │ ├── entrypoint.sh │ ├── .vscode │ │ ├── c_cpp_properties.json │ │ ├── launch.json │ │ ├── settings.json │ │ └── tasks.json │ ├── .devcontainer │ │ ├── Dockerfile │ │ └── devcontainer.json │ ├── setup-ign-ardupilot-sitl.sh │ ├── README.md │ └── LICENSE ├── ignition-ardusub │ ├── ignition-ardusub-foxy │ │ ├── README.md │ │ ├── entrypoint.sh │ │ └── Dockerfile │ └── ignition-ardusub-humble │ │ ├── README.md │ │ ├── entrypoint.sh │ │ └── Dockerfile ├── ros-hackathon │ ├── ros-hackathon-foxy │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile │ ├── ros-hackathon-foxy-dev │ │ ├── entrypoint.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── ros-hackathon-humble │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile │ └── ros-hackathon-humble-dev │ │ ├── entrypoint.sh │ │ ├── Dockerfile │ │ └── README.md ├── ignition-hackathon-gpus │ ├── ignition-hackathon-non-nvidia │ │ ├── ignition-hackathon-non-nvidia-foxy │ │ │ ├── Dockerfile │ │ │ └── README.md │ │ └── ignition-hackathon-non-nvidia-humble │ │ │ ├── Dockerfile │ │ │ └── README.md │ └── ignition-hackathon-nvidia │ │ ├── ignition-hackathon-nvidia-foxy │ │ ├── Dockerfile │ │ └── README.md │ │ └── ignition-hackathon-nvidia-humble │ │ ├── Dockerfile │ │ └── README.md ├── ignition-hackathon │ ├── ignition-hackathon-humble-dev │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile │ ├── ignition-hackathon-humble │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile │ ├── ignition-hackathon-foxy │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile │ └── ignition-hackathon-foxy-dev │ │ ├── entrypoint.sh │ │ ├── README.md │ │ └── Dockerfile ├── README.md └── push-docker-images.sh ├── setup.py ├── launch ├── apm_pluginlists.yaml ├── bluerov_record.launch ├── bluerov.launch ├── bluerov_ign_sim.launch.py ├── bluerov_record.launch.py ├── bluerov_bringup_no_ign.launch.py ├── bluerov_bringup.launch.py └── apm_config.yaml ├── CMakeLists.txt ├── .gitmodules ├── hackathon.rosinstall ├── package.xml ├── scripts ├── bluerov_agent.py ├── random_wall_avoidance.py └── potential_avoidance.py ├── .gitignore ├── PARTICIPANTS_TODO.md ├── .github └── workflows │ └── container.yaml └── README.md /resource/tudelft_hackathon: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dockerfiles/ignition/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | sudo docker build -t ignition:foxy . 3 | ``` 4 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros2_ws/build.sh: -------------------------------------------------------------------------------- 1 | colcon build --merge-install --allow-overriding message_filters orb 2 | -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-foxy/README.md: -------------------------------------------------------------------------------- 1 | # ArduSub image 2 | 3 | ```bash 4 | $ sudo docker build -t ardusub . 5 | ``` 6 | 7 | xhost +local:root 8 | -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-humble/README.md: -------------------------------------------------------------------------------- 1 | # ArduSub image 2 | 3 | ```bash 4 | $ sudo docker build -t ardusub . 5 | ``` 6 | 7 | xhost +local:root 8 | -------------------------------------------------------------------------------- /dockerfiles/ignition/ignition-foxy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/ign_ws/install/setup.bash" 7 | 8 | exec "$@" 9 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros1_ws/src/beginner_tutorials/launch/talk.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/tudelft_hackathon_ws/install/setup.bash" 7 | 8 | exec "$@" 9 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy-dev/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/tudelft_hackathon_ws/install/setup.bash" 7 | 8 | exec "$@" 9 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/humble/setup.bash" 6 | source "/tudelft_hackathon_ws/install/setup.bash" 7 | 8 | exec "$@" 9 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble-dev/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/humble/setup.bash" 6 | source "/tudelft_hackathon_ws/install/setup.bash" 7 | 8 | exec "$@" 9 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy/README.md: -------------------------------------------------------------------------------- 1 | # ROS2 foxy + hackathon workspace image 2 | 3 | ```Bash 4 | $ sudo docker run -it --rm ros-foxy-hackathon ros2 launch tudelft_hackathon bluerov_bringup_no_ign.launch.py 5 | ``` 6 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble/README.md: -------------------------------------------------------------------------------- 1 | # ROS2 foxy + hackathon workspace image 2 | 3 | ```Bash 4 | $ sudo docker run -it --rm ros-foxy-hackathon ros2 launch tudelft_hackathon bluerov_bringup_no_ign.launch.py 5 | ``` 6 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/ign_ws/install/setup.bash" 7 | source "/tudelft_hackathon_ws/install/setup.bash" 8 | 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-humble/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/humble/setup.bash" 6 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 7 | . ~/.profile 8 | 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-foxy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/ign_ws/install/setup.bash" 7 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 8 | . ~/.profile 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:hackathon 2 | 3 | USER root 4 | RUN apt update && apt install -y --no-install-recommends \ 5 | libgl1-mesa-glx \ 6 | libgl1-mesa-dri \ 7 | && rm -rf /var/lib/apt/lists/ 8 | USER docker 9 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:hackathon 2 | 3 | ENV NVIDIA_VISIBLE_DEVICES \ 4 | ${NVIDIA_VISIBLE_DEVICES:-all} 5 | ENV NVIDIA_DRIVER_CAPABILITIES \ 6 | ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics 7 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble-dev/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/humble/setup.bash" 6 | source "/home/docker/tudelft_hackathon_ws/install/setup.bash" 7 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 8 | . ~/.profile 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/humble/setup.bash" 6 | source "/home/docker/tudelft_hackathon_ws/install/setup.bash" 7 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 8 | . ~/.profile 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from catkin_pkg.python_setup import generate_distutils_setup 3 | 4 | package_name ='tudelft_hackathon' 5 | 6 | setup(data_files=[ 7 | ('share/' + package_name, ['package.xml']), 8 | ('share/ament_index/resource_index/packages', 9 | ['resource/' + package_name]), 10 | ]) 11 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/ign_ws/install/setup.bash" 7 | source "/home/docker/tudelft_hackathon_ws/install/setup.bash" 8 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 9 | . ~/.profile 10 | 11 | exec "$@" 12 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy-dev/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | source "/opt/ros/foxy/setup.bash" 6 | source "/ign_ws/install/setup.bash" 7 | source "/home/docker/tudelft_hackathon_ws/install/setup.bash" 8 | source "/home/docker/ardupilot/Tools/completion/completion.bash" 9 | . ~/.profile 10 | 11 | exec "$@" 12 | -------------------------------------------------------------------------------- /dockerfiles/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfiles 2 | 3 | Dockerfiles used to run everything required for the hackathon 4 | 5 | ## Images hierarchy 6 | - `ros:foxy-ros-core` 7 | - `rezenders/ignition:foxy` 8 | - `rezenders/ignition:foxy-ardusub` 9 | - `rezenders/ignition:hackathon` 10 | - `rezenders/ignition:hackathon-nvidia` or `rezenders/ignition:hackathon-non-nvidia` 11 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE="ghcr.io/remaro-network/tudelft_hackathon_base:latest" 2 | FROM $BASE_IMAGE 3 | 4 | ENV NVIDIA_VISIBLE_DEVICES \ 5 | ${NVIDIA_VISIBLE_DEVICES:-all} 6 | ENV NVIDIA_DRIVER_CAPABILITIES \ 7 | ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics 8 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy-dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ros-foxy-hackathon 2 | 3 | COPY . /tudelft_hackathon_ws/src/tudelft_hackathon/ 4 | RUN [ "/bin/bash","-c","source /opt/ros/foxy/setup.bash \ 5 | && colcon build --symlink-install"] 6 | 7 | COPY dockerfiles/ros-foxy-hackathon-dev/entrypoint.sh / 8 | ENTRYPOINT ["/entrypoint.sh"] 9 | CMD ["bash"] 10 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros2_ws/ros1_bridge.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | # steps for running ros1 bridge 4 | echo "-- source noetic setup" 5 | . /opt/ros/noetic/setup.bash 6 | 7 | echo "-- source foxy setup" 8 | . /opt/ros/foxy/setup.bash 9 | 10 | echo "-- export master uri" 11 | export ROS_MASTER_URI=http://localhost:11311 12 | 13 | echo "-- run bridge" 14 | ros2 run ros1_bridge dynamic_bridge -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE="ghcr.io/remaro-network/tudelft_hackathon_base:latest" 2 | FROM $BASE_IMAGE 3 | 4 | USER root 5 | RUN apt update && apt install -y --no-install-recommends \ 6 | libgl1-mesa-glx \ 7 | libgl1-mesa-dri \ 8 | && rm -rf /var/lib/apt/lists/ 9 | USER docker 10 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble-dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ros-hackathon-humble 2 | 3 | COPY . /tudelft_hackathon_ws/src/tudelft_hackathon/ 4 | RUN [ "/bin/bash","-c","source /opt/ros/humble/setup.bash \ 5 | && colcon build --symlink-install"] 6 | 7 | COPY dockerfiles/ros-hackathon/ros-hackathon-humble-dev/entrypoint.sh / 8 | ENTRYPOINT ["/entrypoint.sh"] 9 | CMD ["bash"] 10 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy/README.md: -------------------------------------------------------------------------------- 1 | # Ignition bluerov2 image 2 | 3 | ```Bash 4 | $ sudo docker build -t ignition:foxy-hackathon . 5 | ``` 6 | 7 | ```Bash 8 | $ xhost +local:root 9 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:foxy-hackathon ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py 10 | ``` 11 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble/README.md: -------------------------------------------------------------------------------- 1 | # Ignition bluerov2 image 2 | 3 | ```Bash 4 | $ sudo docker build -t ignition:foxy-hackathon . 5 | ``` 6 | 7 | ```Bash 8 | $ xhost +local:root 9 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:foxy-hackathon ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py 10 | ``` 11 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy-dev/README.md: -------------------------------------------------------------------------------- 1 | # ROS2 foxy + hackathon workspace image 2 | 3 | ```Bash 4 | $ cd tudelft_hackathon_ws/src/tudelft_hackathon 5 | $ sudo docker build -f dockerfiles/ros-foxy-hackathon-dev/Dockerfile -t ros-foxy-hackathon:dev . 6 | ``` 7 | 8 | ```Bash 9 | $ sudo docker run -it --rm ros-foxy-hackathon:dev ros2 launch tudelft_hackathon bluerov_bringup_no_ign.launch.py 10 | ``` 11 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble-dev/README.md: -------------------------------------------------------------------------------- 1 | # ROS2 foxy + hackathon workspace image 2 | 3 | ```Bash 4 | $ cd tudelft_hackathon_ws/src/tudelft_hackathon 5 | $ sudo docker build -f dockerfiles/ros-foxy-hackathon-dev/Dockerfile -t ros-foxy-hackathon:dev . 6 | ``` 7 | 8 | ```Bash 9 | $ sudo docker run -it --rm ros-foxy-hackathon:dev ros2 launch tudelft_hackathon bluerov_bringup_no_ign.launch.py 10 | ``` 11 | -------------------------------------------------------------------------------- /launch/apm_pluginlists.yaml: -------------------------------------------------------------------------------- 1 | /mavros/**: 2 | ros__parameters: 3 | plugin_denylist: 4 | # common 5 | - actuator_control 6 | - ftp 7 | - hil 8 | # extras 9 | - altitude 10 | - debug_value 11 | - image_pub 12 | - px4flow 13 | - vibration 14 | - vision_speed_estimate 15 | - wheel_odometry 16 | 17 | # plugin_allowlist: 18 | # - 'sys_*' 19 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy-dev/README.md: -------------------------------------------------------------------------------- 1 | # Ignition bluerov2 image 2 | 3 | ```Bash 4 | $ cd tudelft_hackathon_ws/src/tudelft_hackathon 5 | $ sudo docker build -f dockerfiles/ignition-foxy-hackathon-dev/Dockerfile -t ignition:foxy-hackathon-dev . 6 | ``` 7 | 8 | ```Bash 9 | $ xhost +local:root 10 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:foxy-hackathon-dev ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py 11 | ``` 12 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble-dev/README.md: -------------------------------------------------------------------------------- 1 | # Ignition bluerov2 image 2 | 3 | ```Bash 4 | $ cd tudelft_hackathon_ws/src/tudelft_hackathon 5 | $ sudo docker build -f dockerfiles/ignition-foxy-hackathon-dev/Dockerfile -t ignition:foxy-hackathon-dev . 6 | ``` 7 | 8 | ```Bash 9 | $ xhost +local:root 10 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:foxy-hackathon-dev ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py 11 | ``` 12 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy-dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:hackathon-nvidia 2 | 3 | COPY . /home/docker/tudelft_hackathon_ws/src/tudelft_hackathon/ 4 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 1' \ 5 | && source /opt/ros/foxy/setup.bash \ 6 | && colcon build --symlink-install"] 7 | 8 | WORKDIR /home/docker/tudelft_hackathon_ws/ 9 | 10 | COPY dockerfiles/ignition-foxy-hackathon-dev/entrypoint.sh /home/docker/ 11 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 12 | CMD ["bash"] 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(tudelft_hackathon) 3 | 4 | find_package(ament_cmake REQUIRED COMPONENTS) 5 | find_package(ament_cmake_python REQUIRED COMPONENTS) 6 | find_package(rclpy REQUIRED) 7 | find_package(mavros_msgs REQUIRED) 8 | 9 | install(PROGRAMS 10 | scripts/bluerov_agent.py 11 | scripts/random_wall_avoidance.py 12 | scripts/potential_avoidance.py 13 | DESTINATION lib/${PROJECT_NAME} 14 | ) 15 | 16 | install(DIRECTORY launch 17 | DESTINATION share/${PROJECT_NAME} 18 | ) 19 | 20 | ament_package() 21 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble-dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:hackathon-nvidia-humble 2 | 3 | COPY . /home/docker/tudelft_hackathon_ws/src/tudelft_hackathon/ 4 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 1' \ 5 | && source /opt/ros/humble/setup.bash \ 6 | && colcon build --symlink-install"] 7 | 8 | WORKDIR /home/docker/tudelft_hackathon_ws/ 9 | 10 | COPY dockerfiles/ignition-hackathon/ignition-hackathon-humble-dev/entrypoint.sh /home/docker/ 11 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 12 | CMD ["bash"] 13 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-foxy/README.md: -------------------------------------------------------------------------------- 1 | #Ignition-nvidia image 2 | 3 | ## Install nvidia-docker 4 | Follow instructions on this [link](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installing-on-ubuntu-and-debian) 5 | 6 | ## Build image 7 | 8 | ```Bash 9 | $ sudo docker build -t ignition:foxy-nvidia . 10 | ``` 11 | 12 | ## Run image 13 | 14 | ```Bash 15 | $ xhost +local:root 16 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:nvidia ign gazebo 17 | ``` 18 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-humble/README.md: -------------------------------------------------------------------------------- 1 | #Ignition-nvidia image 2 | 3 | ## Install nvidia-docker 4 | Follow instructions on this [link](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installing-on-ubuntu-and-debian) 5 | 6 | ## Build image 7 | 8 | ```Bash 9 | $ sudo docker build -t ignition:foxy-nvidia . 10 | ``` 11 | 12 | ## Run image 13 | 14 | ```Bash 15 | $ xhost +local:root 16 | $ sudo docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ignition:nvidia ign gazebo 17 | ``` 18 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/dpds/**", 8 | "/opt/ros/foxy/include/**" 9 | ], 10 | "defines": [], 11 | "compilerPath": "/usr/bin/gcc", 12 | "compileCommands": "${workspaceFolder}/build/compile_commands.json", 13 | "cStandard": "c99", 14 | "cppStandard": "c++14", 15 | "intelliSenseMode": "clang-x64" 16 | } 17 | ], 18 | "version": 4 19 | } -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dockerfiles/ros1-2-ignition/ardupilot"] 2 | path = dockerfiles/ros1-2-ignition/ardupilot 3 | url = https://github.com/ArduPilot/ardupilot.git 4 | [submodule "dockerfiles/ros1-2-ignition/ros2_ws/src/bluerov2_ignition"] 5 | path = dockerfiles/ros1-2-ignition/ros2_ws/src/bluerov2_ignition 6 | url = https://github.com/Rezenders/bluerov2_ignition.git 7 | [submodule "dockerfiles/ros1-2-ignition/ardupilot_gazebo"] 8 | path = dockerfiles/ros1-2-ignition/ardupilot_gazebo 9 | url = https://github.com/ArduPilot/ardupilot_gazebo 10 | [submodule "dockerfiles/ros1-2-ignition/ros2_ws/src/remaro_worlds"] 11 | path = dockerfiles/ros1-2-ignition/ros2_ws/src/remaro_worlds 12 | url = https://github.com/remaro-network/remaro_worlds.git 13 | -------------------------------------------------------------------------------- /dockerfiles/ignition/ignition-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:humble-ros-core-jammy 2 | 3 | RUN apt update && apt install -y --no-install-recommends \ 4 | wget \ 5 | gnupg \ 6 | lsb-release \ 7 | && rm -rf /var/lib/apt/lists/ 8 | 9 | RUN wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg 10 | RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null 11 | 12 | RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y \ 13 | gz-garden \ 14 | && rm -rf /var/lib/apt/lists/ 15 | 16 | CMD ["bash"] 17 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-foxy/README.md: -------------------------------------------------------------------------------- 1 | #Ignition-non-nvidia image 2 | 3 | ## Info 4 | http://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration 5 | 6 | ## Build image 7 | 8 | ```Bash 9 | $ sudo docker build -t ignition:foxy-non-nvidia . 10 | ``` 11 | 12 | ## AMD 13 | 14 | ```Bash 15 | $ xhost +local:root 16 | $ sudo docker run --rm -it --device=/dev/dri --group-add video --volume=/tmp/.X11-unix:/tmp/.X11-unix --env="DISPLAY=$DISPLAY" ignition:non-nvidia ign gazebo 17 | ``` 18 | 19 | ## Intel 20 | 21 | ```Bash 22 | $ xhost +local:root 23 | $ sudo docker run --rm -it --device=/dev/dri:/dev/dri --volume=/tmp/.X11-unix:/tmp/.X11-unix --env="DISPLAY=$DISPLAY" ignition:non-nvidia ign gazebo 24 | ``` 25 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-humble/README.md: -------------------------------------------------------------------------------- 1 | #Ignition-non-nvidia image 2 | 3 | ## Info 4 | http://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration 5 | 6 | ## Build image 7 | 8 | ```Bash 9 | $ sudo docker build -t ignition:foxy-non-nvidia . 10 | ``` 11 | 12 | ## AMD 13 | 14 | ```Bash 15 | $ xhost +local:root 16 | $ sudo docker run --rm -it --device=/dev/dri --group-add video --volume=/tmp/.X11-unix:/tmp/.X11-unix --env="DISPLAY=$DISPLAY" ignition:non-nvidia ign gazebo 17 | ``` 18 | 19 | ## Intel 20 | 21 | ```Bash 22 | $ xhost +local:root 23 | $ sudo docker run --rm -it --device=/dev/dri:/dev/dri --volume=/tmp/.X11-unix:/tmp/.X11-unix --env="DISPLAY=$DISPLAY" ignition:non-nvidia ign gazebo 24 | ``` 25 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros2_ws/src/cpp_pubsub/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cpp_pubsub 5 | 0.0.0 6 | TODO: Package description 7 | ros 8 | TODO: License declaration 9 | 10 | rclcpp 11 | std_msgs 12 | 13 | ament_cmake 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | 22 | -------------------------------------------------------------------------------- /hackathon.rosinstall: -------------------------------------------------------------------------------- 1 | repositories: 2 | bluerov2_ignition: 3 | type: git 4 | url: https://github.com/Rezenders/bluerov2_ignition.git 5 | version: 6756666 6 | mavros: 7 | type: git 8 | url: https://github.com/mavlink/mavros.git 9 | version: 6a26851 10 | mavros_wrapper: 11 | type: git 12 | url: https://github.com/remaro-network/mavros_wrapper.git 13 | version: ros2 14 | ping360_sonar: 15 | type: git 16 | url: https://github.com/CentraleNantesRobotics/ping360_sonar.git 17 | version: fa53b8f 18 | remaro_worlds: 19 | type: git 20 | url: https://github.com/remaro-network/remaro_worlds.git 21 | version: ign-garden 22 | tudelft_hackathon: 23 | type: git 24 | url: https://github.com/remaro-network/tudelft_hackathon.git 25 | version: ros2 26 | ros_gz: 27 | type: git 28 | url: https://github.com/gazebosim/ros_gz.git 29 | version: 151d3d8 30 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros2_ws/src/cpp_pubsub/src/subscriber_member_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rclcpp/rclcpp.hpp" 4 | #include "std_msgs/msg/string.hpp" 5 | using std::placeholders::_1; 6 | 7 | class MinimalSubscriber : public rclcpp::Node 8 | { 9 | public: 10 | MinimalSubscriber() 11 | : Node("minimal_subscriber") 12 | { 13 | subscription_ = this->create_subscription( 14 | "chatter", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); 15 | } 16 | 17 | private: 18 | void topic_callback(const std_msgs::msg::String::SharedPtr msg) const 19 | { 20 | RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str()); 21 | } 22 | rclcpp::Subscription::SharedPtr subscription_; 23 | }; 24 | 25 | int main(int argc, char * argv[]) 26 | { 27 | rclcpp::init(argc, argv); 28 | rclcpp::spin(std::make_shared()); 29 | rclcpp::shutdown(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:hackathon-nvidia 2 | 3 | USER root 4 | ENV DEBIAN_FRONTEND=noninteractive 5 | RUN apt-get update \ 6 | && apt-get -y install --no-install-recommends nano ros-foxy-rviz2 terminator gdb \ 7 | && rm -rf /var/lib/apt/lists/ 8 | USER docker 9 | 10 | RUN echo "alias sf='source /opt/ros/foxy/setup.bash'" >> /home/docker/.bashrc 11 | RUN echo "alias s='source install/setup.bash'" >> /home/docker/.bashrc 12 | RUN echo "alias m='bash build.sh'" >> /home/docker/.bashrc 13 | RUN echo "source /home/docker/tudelft_hackathon_ws/install/setup.bash" >> /home/docker/.bashrc 14 | RUN echo "source /ign_ws/install/setup.bash" >> /home/docker/.bashrc 15 | RUN echo "source /home/docker/ardupilot/Tools/completion/completion.bash" >> /home/docker/.bashrc 16 | 17 | COPY . /home/docker/tudelft_hackathon_ws/src/tudelft_hackathon/ 18 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 1' \ 19 | && source /opt/ros/foxy/setup.bash \ 20 | && colcon build --symlink-install"] 21 | 22 | WORKDIR /home/docker/tudelft_hackathon_ws/ 23 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | tudelft_hackathon 4 | 0.0.0 5 | TU Delft REMARO hackathon package 6 | 7 | Gustavo Rezende 8 | 9 | 10 | 11 | 12 | 13 | TODO 14 | 15 | ament_cmake 16 | ament_cmake_python 17 | 18 | rclpy 19 | rclpy 20 | rclpy 21 | 22 | mavros 23 | mavros 24 | mavros 25 | 26 | mavros_msgs 27 | mavros_wrapper 28 | ros_gz 29 | 30 | 31 | ament_cmake 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/setup-ign-ardupilot-sitl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pip install future 3 | pip3 install mavproxy pymavlink 4 | 5 | cd ardupilot_gazebo 6 | mkdir -p build && cd build 7 | cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo 8 | make -j4 9 | cd .. 10 | cd .. 11 | echo 'export IGN_GAZEBO_SYSTEM_PLUGIN_PATH=$PWD/ardupilot_gazebo/build:${IGN_GAZEBO_SYSTEM_PLUGIN_PATH}' >> ~/.bashrc 12 | echo 'export IGN_GAZEBO_RESOURCE_PATH=$PWD/ardupilot_gazebo/models:$PWD/ardupilot_gazebo/worlds:${IGN_GAZEBO_RESOURCE_PATH}' >> ~/.bashrc 13 | 14 | echo 'export IGN_GAZEBO_RESOURCE_PATH=$PWD/ros2_ws/src/bluerov2_ignition/models:$PWD/ros2_ws/src/bluerov2_ignition/worlds:${IGN_GAZEBO_RESOURCE_PATH}' >> ~/.bashrc 15 | echo 'export IGN_GAZEBO_RESOURCE_PATH=$PWD/ros2_ws/src/remaro_worlds/models:$PWD/ros2_ws/src/remaro_worlds/worlds:${IGN_GAZEBO_RESOURCE_PATH}' >> ~/.bashrc 16 | 17 | cd ardupilot 18 | git checkout ArduSub-stable -b new-branch 19 | git submodule update --init --recursive 20 | Tools/environment_install/install-prereqs-ubuntu.sh -y 21 | . ~/.profile 22 | ./waf clean 23 | ./waf configure --board Pixhawk1 24 | ./waf sub 25 | # Tools/autotest/sim_vehicle.py -L RATBeach -v ArduSub --model=JSON --out=udp:0.0.0.0:14550 --console -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/vscode-remote/devcontainer.json for format details. 2 | { 3 | "dockerFile": "Dockerfile", 4 | "build": { 5 | "args": { 6 | "WORKSPACE": "${containerWorkspaceFolder}" 7 | } 8 | }, 9 | "remoteUser": "docker", 10 | "runArgs": [ 11 | "--network=host", 12 | "--cap-add=SYS_PTRACE", 13 | "--security-opt=seccomp:unconfined", 14 | "--security-opt=apparmor:unconfined", 15 | "--volume=/tmp/.X11-unix:/tmp/.X11-unix", 16 | "--gpus", 17 | "all", 18 | ], 19 | "containerEnv": { "DISPLAY": "${localEnv:DISPLAY}" }, 20 | // Set *default* container specific settings.json values on container create. 21 | "settings": { 22 | "terminal.integrated.profiles.linux": { 23 | "bash": { 24 | "path": "bash" 25 | }, 26 | }, 27 | "terminal.integrated.defaultProfile.linux": "bash" 28 | }, 29 | "extensions": [ 30 | "dotjoshjohnson.xml", 31 | "zachflower.uncrustify", 32 | "ms-azuretools.vscode-docker", 33 | "ms-python.python", 34 | "ms-vscode.cpptools", 35 | "redhat.vscode-yaml", 36 | "smilerobotics.urdf", 37 | "streetsidesoftware.code-spell-checker", 38 | "twxs.cmake", 39 | "yzhang.markdown-all-in-one" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros2_ws/src/cpp_pubsub/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(cpp_pubsub) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++14 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 14) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | # uncomment the following section in order to fill in 21 | # further dependencies manually. 22 | # find_package( REQUIRED) 23 | 24 | find_package(rclcpp REQUIRED) 25 | find_package(std_msgs REQUIRED) 26 | 27 | add_executable(listener src/subscriber_member_function.cpp) 28 | ament_target_dependencies(listener rclcpp std_msgs) 29 | 30 | install(TARGETS 31 | listener 32 | DESTINATION lib/${PROJECT_NAME}) 33 | 34 | if(BUILD_TESTING) 35 | find_package(ament_lint_auto REQUIRED) 36 | # the following line skips the linter which checks for copyrights 37 | # uncomment the line when a copyright and license is not present in all source files 38 | #set(ament_cmake_copyright_FOUND TRUE) 39 | # the following line skips cpplint (only works in a git repo) 40 | # uncomment the line when this package is not in a git repo 41 | #set(ament_cmake_cpplint_FOUND TRUE) 42 | ament_lint_auto_find_test_dependencies() 43 | endif() 44 | 45 | ament_package() 46 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:foxy-ros-core 2 | 3 | RUN apt update && apt install -y --no-install-recommends\ 4 | git \ 5 | wget \ 6 | build-essential \ 7 | libboost-all-dev \ 8 | python3-pip \ 9 | python3-vcstool \ 10 | python3-rosdep \ 11 | python-is-python3 \ 12 | python3-colcon-common-extensions \ 13 | && rm -rf /var/lib/apt/lists/ 14 | 15 | RUN rosdep init 16 | 17 | RUN mkdir -p /tudelft_hackathon_ws/src 18 | 19 | WORKDIR /tudelft_hackathon_ws 20 | 21 | RUN wget https://raw.githubusercontent.com/remaro-network/tudelft_hackathon/ros2/hackathon.rosinstall 22 | RUN vcs import src < hackathon.rosinstall --recursive 23 | 24 | RUN [ "/bin/bash","-c","source /opt/ros/foxy/setup.bash \ 25 | && apt update && rosdep update \ 26 | && rosdep install --from-paths src --ignore-src -r -y \ 27 | && rm -rf /var/lib/apt/lists/"] 28 | 29 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 2' \ 30 | && source /opt/ros/foxy/setup.bash \ 31 | && colcon build --symlink-install"] 32 | 33 | WORKDIR /tudelft_hackathon_ws/src/mavros/mavros/scripts 34 | RUN [ "/bin/bash","-c","apt update \ 35 | && ./install_geographiclib_datasets.sh \ 36 | && rm -rf /var/lib/apt/lists/"] 37 | 38 | WORKDIR /tudelft_hackathon_ws/ 39 | ENV IGN_GAZEBO_RESOURCE_PATH=/tudelft_hackathon_ws/src/remaro_worlds/models:/remaro_worlds/worlds:${IGN_GAZEBO_RESOURCE_PATH} 40 | 41 | COPY entrypoint.sh / 42 | ENTRYPOINT ["/entrypoint.sh"] 43 | CMD ["bash"] 44 | -------------------------------------------------------------------------------- /dockerfiles/ros-hackathon/ros-hackathon-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:humble 2 | 3 | RUN apt update && apt install -y --no-install-recommends\ 4 | git \ 5 | wget \ 6 | build-essential \ 7 | libboost-all-dev \ 8 | python3-pip \ 9 | python3-vcstool \ 10 | python3-rosdep \ 11 | python-is-python3 \ 12 | python3-colcon-common-extensions \ 13 | && rm -rf /var/lib/apt/lists/ 14 | 15 | RUN rosdep init 16 | 17 | RUN mkdir -p /tudelft_hackathon_ws/src 18 | 19 | WORKDIR /tudelft_hackathon_ws 20 | 21 | RUN wget https://raw.githubusercontent.com/remaro-network/tudelft_hackathon/ros2/hackathon.rosinstall 22 | RUN vcs import src < hackathon.rosinstall --recursive 23 | 24 | RUN [ "/bin/bash","-c","source /opt/ros/humble/setup.bash \ 25 | && apt update && rosdep update \ 26 | && rosdep install --from-paths src --ignore-src -r -y \ 27 | && rm -rf /var/lib/apt/lists/"] 28 | 29 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 2' \ 30 | && source /opt/ros/humble/setup.bash \ 31 | && colcon build --symlink-install"] 32 | 33 | WORKDIR /tudelft_hackathon_ws/src/mavros/mavros/scripts 34 | RUN [ "/bin/bash","-c","apt update \ 35 | && ./install_geographiclib_datasets.sh \ 36 | && rm -rf /var/lib/apt/lists/"] 37 | 38 | WORKDIR /tudelft_hackathon_ws/ 39 | ENV GZ_SIM_RESOURCE_PATH=/tudelft_hackathon_ws/src/remaro_worlds/models:/remaro_worlds/worlds:${GZ_SIM_RESOURCE_PATH} 40 | 41 | COPY entrypoint.sh / 42 | ENTRYPOINT ["/entrypoint.sh"] 43 | CMD ["bash"] 44 | -------------------------------------------------------------------------------- /launch/bluerov_record.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /launch/bluerov.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /scripts/bluerov_agent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import rclpy 4 | from rclpy.node import Node 5 | import threading 6 | 7 | from mavros_wrapper.ardusub_wrapper import * 8 | 9 | def mission(ardusub): 10 | 11 | service_timer = ardusub.create_rate(2) 12 | while ardusub.status.mode != "MANUAL": 13 | ardusub.set_mode("MANUAL") 14 | service_timer.sleep() 15 | 16 | print("Manual mode selected") 17 | 18 | while ardusub.status.armed == False: 19 | ardusub.arm_motors(True) 20 | service_timer.sleep() 21 | 22 | print("Thrusters armed") 23 | 24 | print("Initializing mission") 25 | 26 | timer = ardusub.create_rate(0.5) # Hz 27 | 28 | ardusub.toogle_rc_override(True) 29 | ardusub.set_rc_override_channels(forward=0.5) 30 | timer.sleep() 31 | ardusub.set_rc_override_channels(lateral=0.5) 32 | timer.sleep() 33 | ardusub.set_rc_override_channels(forward=-0.5) 34 | timer.sleep() 35 | ardusub.set_rc_override_channels(lateral=-0.5) 36 | timer.sleep() 37 | ardusub.set_rc_override_channels(lateral=0) 38 | ardusub.toogle_rc_override(False) 39 | 40 | print("Mission completed") 41 | 42 | if __name__ == '__main__': 43 | print("Starting Bluerov agent node") 44 | 45 | # Initialize ros node 46 | rclpy.init(args=sys.argv) 47 | 48 | ardusub = BlueROVArduSubWrapper("ardusub_node") 49 | 50 | thread = threading.Thread(target=rclpy.spin, args=(ardusub, ), daemon=True) 51 | thread.start() 52 | 53 | mission(ardusub) 54 | 55 | ardusub.destroy_node() 56 | rclpy.shutdown() 57 | thread.join() 58 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | // Example launch of a python file 8 | { 9 | "name": "Python: Current File", 10 | "type": "python", 11 | "request": "launch", 12 | "program": "${file}", 13 | "console": "integratedTerminal", 14 | }, 15 | // Example gdb launch of a ros executable 16 | { 17 | "name": "(gdb) Launch", 18 | "type": "cppdbg", 19 | "request": "launch", 20 | "program": "${workspaceFolder}/ros2/install/${input:package}/lib/${input:package}/${input:program}", 21 | "args": [], 22 | "preLaunchTask": "build", 23 | "stopAtEntry": true, 24 | "cwd": "${workspaceFolder}/ros2/", 25 | "externalConsole": false, 26 | "MIMode": "gdb", 27 | "miDebuggerPath": "/usr/bin/gdb", 28 | "setupCommands": [ 29 | { 30 | "description": "Enable pretty-printing for gdb", 31 | "text": "-enable-pretty-printing", 32 | "ignoreFailures": true 33 | } 34 | ] 35 | } 36 | ], 37 | "inputs": [ 38 | { 39 | "id": "package", 40 | "type": "promptString", 41 | "description": "Package name", 42 | "default": "examples_rclcpp_minimal_publisher" 43 | }, 44 | { 45 | "id": "program", 46 | "type": "promptString", 47 | "description": "Program name", 48 | "default": "publisher_member_function" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:foxy 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update && apt-get install -y\ 6 | git \ 7 | sudo \ 8 | tzdata \ 9 | locales \ 10 | lsb-release \ 11 | build-essential \ 12 | keyboard-configuration \ 13 | && rm -rf /var/lib/apt/lists/ 14 | 15 | # Set the locale 16 | RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ 17 | locale-gen 18 | ENV LANG en_US.UTF-8 19 | ENV LANGUAGE en_US:en 20 | ENV LC_ALL en_US.UTF-8 21 | 22 | # create new user 23 | RUN adduser --disabled-password \ 24 | --gecos '' docker 25 | 26 | # Add new user docker to sudo group 27 | RUN adduser docker sudo 28 | 29 | # Ensure sudo group users are not asked for a password when using 30 | # sudo command by ammending sudoers file 31 | RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> \ 32 | /etc/sudoers 33 | 34 | # now we can set USER to the user we just created 35 | USER docker 36 | ENV DEBIAN_FRONTEND noninteractive 37 | 38 | WORKDIR /home/docker/ 39 | RUN git clone https://github.com/ArduPilot/ardupilot.git -b Sub-4.1 --recurse 40 | WORKDIR /home/docker/ardupilot 41 | 42 | # RUN git config --global --add safe.directory /ardupilot 43 | RUN USER=docker Tools/environment_install/install-prereqs-ubuntu.sh -y 44 | RUN . ~/.profile 45 | 46 | ENV PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH 47 | ENV PATH=$PATH:/home/docker/ardupilot/Tools/autotest 48 | ENV PATH=/usr/lib/ccache:$PATH 49 | 50 | WORKDIR /home/docker/ardupilot 51 | RUN ["/bin/bash","-c","./waf configure && make sub"] 52 | WORKDIR /home/docker/ardupilot/ArduSub 53 | 54 | COPY entrypoint.sh /home/docker/entrypoint.sh 55 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 56 | -------------------------------------------------------------------------------- /dockerfiles/ignition/ignition-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:foxy-ros-core 2 | 3 | RUN apt update && apt install -y --no-install-recommends \ 4 | git \ 5 | wget \ 6 | curl \ 7 | gnupg \ 8 | lsb-release \ 9 | python3-pip \ 10 | && rm -rf /var/lib/apt/lists/ 11 | 12 | RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' 13 | RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add - 14 | 15 | RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends\ 16 | python3-vcstool \ 17 | python3-colcon-common-extensions \ 18 | && rm -rf /var/lib/apt/lists/ 19 | 20 | RUN mkdir -p /ign_ws/src 21 | WORKDIR /ign_ws/src 22 | RUN wget https://raw.githubusercontent.com/Rezenders/bluerov2_ignition/main/garden.repos 23 | RUN vcs import < garden.repos 24 | 25 | RUN wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg 26 | RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null 27 | 28 | RUN apt update && apt install -y --no-install-recommends\ 29 | $(sort -u $(find . -iname 'packages-'`lsb_release -cs`'.apt' -o -iname 'packages.apt' | grep -v '/\.git/') | sed '/ignition\|sdf/d' | tr '\n' ' ') \ 30 | && rm -rf /var/lib/apt/lists/ 31 | 32 | WORKDIR /ign_ws/ 33 | 34 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 2' \ 35 | && colcon build --cmake-args -DBUILD_TESTING=OFF --merge-install --executor sequential"] 36 | 37 | COPY entrypoint.sh / 38 | ENTRYPOINT ["/entrypoint.sh"] 39 | CMD ["bash"] 40 | -------------------------------------------------------------------------------- /scripts/random_wall_avoidance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import rclpy 4 | import random 5 | import threading 6 | 7 | from rclpy.node import Node 8 | 9 | from sensor_msgs.msg import LaserScan 10 | from mavros_wrapper.ardusub_wrapper import * 11 | 12 | 13 | def laser_scan_cb(msg, ardusub): 14 | min_distance = 1.5 15 | yaw_speed = 0.3 16 | forward_speed = 0.15 17 | allGreater = True 18 | for scan in msg.ranges: 19 | if scan < min_distance: 20 | allGreater = False 21 | _yaw_speed = (-1)**random.choice([1, 2])*yaw_speed 22 | ardusub.set_rc_override_channels( 23 | forward=-forward_speed/4, 24 | yaw=_yaw_speed) 25 | break 26 | if allGreater: 27 | ardusub.set_rc_override_channels(forward=forward_speed) 28 | 29 | 30 | if __name__ == '__main__': 31 | print("Starting wall avoidance. Let's swim!") 32 | 33 | # Initialize ros node 34 | rclpy.init(args=sys.argv) 35 | 36 | ardusub = BlueROVArduSubWrapper("ardusub_node") 37 | 38 | thread = threading.Thread(target=rclpy.spin, args=(ardusub, ), daemon=True) 39 | thread.start() 40 | 41 | service_timer = ardusub.create_rate(2) 42 | while ardusub.status.mode != "ALT_HOLD": 43 | ardusub.set_mode("ALT_HOLD") 44 | service_timer.sleep() 45 | 46 | print("ALT HOLD mode selected") 47 | 48 | while ardusub.status.armed is False: 49 | ardusub.arm_motors(True) 50 | service_timer.sleep() 51 | 52 | print("Thrusters armed") 53 | 54 | print("Initializing mission") 55 | 56 | ardusub.toogle_rc_override(True) 57 | ardusub.set_rc_override_channels(forward=0.35) 58 | 59 | laser_subscriber = ardusub.create_subscription( 60 | LaserScan, '/scan', (lambda msg: laser_scan_cb(msg, ardusub)), 10) 61 | 62 | rate = ardusub.create_rate(2) 63 | try: 64 | while rclpy.ok(): 65 | rate.sleep() 66 | except KeyboardInterrupt: 67 | pass 68 | 69 | ardusub.destroy_node() 70 | rclpy.shutdown() 71 | -------------------------------------------------------------------------------- /dockerfiles/ignition-ardusub/ignition-ardusub-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE="ghcr.io/remaro-network/ignition-humble:latest" 2 | FROM $BASE_IMAGE 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | 6 | RUN apt-get update && apt-get install -y\ 7 | git \ 8 | sudo \ 9 | tzdata \ 10 | locales \ 11 | lsb-release \ 12 | build-essential \ 13 | keyboard-configuration \ 14 | && rm -rf /var/lib/apt/lists/ 15 | 16 | # Set the locale 17 | RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ 18 | locale-gen 19 | ENV LANG en_US.UTF-8 20 | ENV LANGUAGE en_US:en 21 | ENV LC_ALL en_US.UTF-8 22 | 23 | # create new user 24 | RUN adduser --disabled-password \ 25 | --gecos '' docker 26 | 27 | # Add new user docker to sudo group 28 | RUN adduser docker sudo 29 | 30 | # Ensure sudo group users are not asked for a password when using 31 | # sudo command by ammending sudoers file 32 | RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> \ 33 | /etc/sudoers 34 | 35 | # now we can set USER to the user we just created 36 | USER docker 37 | ENV DEBIAN_FRONTEND noninteractive 38 | 39 | WORKDIR /home/docker/ 40 | RUN git clone https://github.com/ArduPilot/ardupilot.git 41 | WORKDIR /home/docker/ardupilot 42 | RUN git checkout 94ba4ec 43 | RUN git submodule update --init --recursive 44 | 45 | # RUN git config --global --add safe.directory /ardupilot 46 | WORKDIR /home/docker/ardupilot/Tools/environment_install/ 47 | RUN rm install-prereqs-ubuntu.sh 48 | RUN wget https://raw.githubusercontent.com/ArduPilot/ardupilot/master/Tools/environment_install/install-prereqs-ubuntu.sh 49 | WORKDIR /home/docker/ardupilot 50 | RUN chmod +x Tools/environment_install/install-prereqs-ubuntu.sh 51 | RUN USER=docker Tools/environment_install/install-prereqs-ubuntu.sh -y 52 | RUN . ~/.profile 53 | 54 | RUN sudo pip3 install -U mavproxy PyYAML 55 | 56 | ENV PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH 57 | ENV PATH=$PATH:$HOME/ardupilot/Tools/autotest 58 | ENV PATH=/usr/lib/ccache:$PATH 59 | 60 | WORKDIR /home/docker/ardupilot 61 | RUN ["/bin/bash","-c","./waf configure && make sub"] 62 | WORKDIR /home/docker/ardupilot/ArduSub 63 | 64 | COPY entrypoint.sh /home/docker/entrypoint.sh 65 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 66 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-humble/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE="ghcr.io/remaro-network/ignition-ardusub-humble:latest" 2 | FROM $BASE_IMAGE 3 | 4 | USER root 5 | RUN apt update && apt install -y --no-install-recommends \ 6 | vim \ 7 | rapidjson-dev \ 8 | libboost-all-dev \ 9 | python3-pip \ 10 | python3-vcstool \ 11 | python3-rosdep \ 12 | python-is-python3 \ 13 | python3-colcon-common-extensions \ 14 | && rm -rf /var/lib/apt/lists/ 15 | 16 | USER docker 17 | 18 | WORKDIR /home/docker/ 19 | RUN git clone https://github.com/ArduPilot/ardupilot_gazebo.git 20 | 21 | WORKDIR /home/docker/ardupilot_gazebo 22 | 23 | RUN [ "/bin/bash","-c","mkdir build && cd build \ 24 | && cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo\ 25 | && make"] 26 | 27 | ENV GZ_SIM_SYSTEM_PLUGIN_PATH=/home/docker/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH} 28 | ENV GZ_SIM_RESOURCE_PATH=/home/docker/ardupilot_gazebo/models:/home/docker/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH} 29 | 30 | RUN mkdir -p /home/docker/tudelft_hackathon_ws/src 31 | 32 | WORKDIR /home/docker/tudelft_hackathon_ws/ 33 | RUN wget https://raw.githubusercontent.com/remaro-network/tudelft_hackathon/ros2/hackathon.rosinstall 34 | RUN vcs import src < hackathon.rosinstall --recursive 35 | 36 | RUN ["/bin/bash", "-c", "source /opt/ros/humble/setup.bash \ 37 | && sudo apt update \ 38 | && sudo rosdep init \ 39 | && rosdep update \ 40 | && rosdep install --from-paths src --ignore-src -r -y \ 41 | && sudo rm -rf /var/lib/apt/lists/"] 42 | 43 | RUN ["/bin/bash", "-c", "sudo ./src/mavros/mavros/scripts/install_geographiclib_datasets.sh"] 44 | 45 | ENV GZ_VERSION="garden" 46 | RUN [ "/bin/bash","-c","source /opt/ros/humble/setup.bash \ 47 | && colcon build --symlink-install"] 48 | 49 | ENV GZ_SIM_RESOURCE_PATH=/home/docker/tudelft_hackathon_ws/src/bluerov2_ignition/models:/home/docker/bluerov2_ignition/worlds:${GZ_SIM_RESOURCE_PATH} 50 | ENV GZ_SIM_RESOURCE_PATH=/home/docker/tudelft_hackathon_ws/src/remaro_worlds/models:/home/docker/tudelft_hackathon_ws/src/remaro_worlds/worlds:${GZ_SIM_RESOURCE_PATH} 51 | 52 | WORKDIR /home/docker/tudelft_hackathon_ws/ 53 | 54 | COPY entrypoint.sh /home/docker/ 55 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 56 | CMD ["bash"] 57 | -------------------------------------------------------------------------------- /launch/bluerov_ign_sim.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | 5 | from launch import LaunchDescription 6 | from launch.actions import DeclareLaunchArgument 7 | from launch.actions import IncludeLaunchDescription 8 | from launch.actions import ExecuteProcess 9 | from launch.conditions import IfCondition 10 | from launch.launch_description_sources import PythonLaunchDescriptionSource 11 | from launch.substitutions import LaunchConfiguration 12 | 13 | from launch_ros.actions import Node 14 | 15 | 16 | def generate_launch_description(): 17 | ardusub_arg = LaunchConfiguration('ardusub') 18 | ardusub_arg = DeclareLaunchArgument( 19 | 'ardusub', 20 | default_value='false' 21 | ) 22 | 23 | mavros_url_arg = LaunchConfiguration('mavros_url') 24 | mavros_url_arg = DeclareLaunchArgument( 25 | 'mavros_url', 26 | default_value='0.0.0.0:14550', 27 | ) 28 | 29 | pkg_ros_gz_sim = get_package_share_directory('ros_gz_sim') 30 | 31 | gz_sim = IncludeLaunchDescription( 32 | PythonLaunchDescriptionSource( 33 | os.path.join(pkg_ros_gz_sim, 'launch', 'gz_sim.launch.py')), 34 | launch_arguments={ 35 | 'gz_args': '-r room_walls.world' 36 | }.items(), 37 | ) 38 | 39 | # TODO: Pass x, y, z, R, P and Y as parameter 40 | bluerov_spawn = Node( 41 | package='ros_gz_sim', 42 | executable='create', 43 | arguments=[ 44 | '-world', 'walls', 45 | '-file', 'bluerov2_lidar', 46 | '-name', 'bluerov2', 47 | '-x', '10', 48 | '-y', '-6.0', 49 | '-z', '-19.5', 50 | '-Y', '-1.57'] 51 | ) 52 | 53 | # Bridge 54 | bridge = Node( 55 | package='ros_gz_bridge', 56 | executable='parameter_bridge', 57 | arguments=['lidar@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan'], 58 | remappings=[('/lidar', '/scan')], 59 | output='screen' 60 | ) 61 | 62 | return LaunchDescription([ 63 | gz_sim, 64 | bluerov_spawn, 65 | bridge, 66 | ardusub_arg, 67 | mavros_url_arg, 68 | ExecuteProcess( 69 | cmd=[ 70 | 'sim_vehicle.py', '-v', 'ArduSub', 71 | '-L', 'RATBeach', '--model=JSON', 72 | '--out', LaunchConfiguration('mavros_url'), '--console'], 73 | output='screen', 74 | condition=IfCondition(LaunchConfiguration('ardusub')) 75 | ), 76 | ]) 77 | -------------------------------------------------------------------------------- /dockerfiles/ignition-hackathon/ignition-hackathon-foxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rezenders/ignition:foxy-ardusub 2 | 3 | USER root 4 | RUN apt update && apt install -y --no-install-recommends \ 5 | vim \ 6 | rapidjson-dev \ 7 | libboost-all-dev \ 8 | python3-pip \ 9 | python3-vcstool \ 10 | python3-rosdep \ 11 | python-is-python3 \ 12 | python3-colcon-common-extensions \ 13 | && rm -rf /var/lib/apt/lists/ 14 | 15 | RUN rosdep init 16 | 17 | USER docker 18 | 19 | WORKDIR /home/docker/ 20 | RUN git clone https://github.com/ArduPilot/ardupilot_gazebo.git -b ignition-garden 21 | 22 | WORKDIR /home/docker/ardupilot_gazebo 23 | 24 | RUN [ "/bin/bash","-c","source /ign_ws/install/setup.bash \ 25 | && mkdir build && cd build \ 26 | && cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo\ 27 | && make"] 28 | 29 | ENV IGN_GAZEBO_SYSTEM_PLUGIN_PATH=/home/docker/ardupilot_gazebo/build:${IGN_GAZEBO_SYSTEM_PLUGIN_PATH} 30 | ENV IGN_GAZEBO_RESOURCE_PATH=/home/docker/ardupilot_gazebo/models:/home/docker/ardupilot_gazebo/worlds:${IGN_GAZEBO_RESOURCE_PATH} 31 | 32 | RUN mkdir -p /home/docker/tudelft_hackathon_ws/src 33 | 34 | WORKDIR /home/docker/tudelft_hackathon_ws/ 35 | RUN wget https://raw.githubusercontent.com/remaro-network/tudelft_hackathon/ros2/hackathon.rosinstall 36 | RUN vcs import src < hackathon.rosinstall --recursive 37 | 38 | 39 | USER root 40 | 41 | WORKDIR /home/docker/tudelft_hackathon_ws/src/mavros/mavros/scripts 42 | RUN [ "/bin/bash","-c","apt update \ 43 | && ./install_geographiclib_datasets.sh \ 44 | && rm -rf /var/lib/apt/lists/"] 45 | 46 | WORKDIR /home/docker/tudelft_hackathon_ws/ 47 | RUN [ "/bin/bash","-c","source /opt/ros/foxy/setup.bash \ 48 | && apt update && rosdep update \ 49 | && rosdep install --from-paths src --ignore-src -r -y \ 50 | && rm -rf /var/lib/apt/lists/"] 51 | 52 | USER docker 53 | RUN [ "/bin/bash","-c","export MAKEFLAGS='-j 1' \ 54 | && source /opt/ros/foxy/setup.bash \ 55 | && colcon build --symlink-install"] 56 | 57 | ENV IGN_GAZEBO_RESOURCE_PATH=/home/docker/tudelft_hackathon_ws/src/bluerov2_ignition/models:/home/docker/bluerov2_ignition/worlds:${IGN_GAZEBO_RESOURCE_PATH} 58 | ENV IGN_GAZEBO_RESOURCE_PATH=/home/docker/tudelft_hackathon_ws/src/remaro_worlds/models:/home/docker/tudelft_hackathon_ws/src/remaro_worlds/worlds:${IGN_GAZEBO_RESOURCE_PATH} 59 | 60 | WORKDIR /home/docker/tudelft_hackathon_ws/ 61 | 62 | COPY entrypoint.sh /home/docker/ 63 | ENTRYPOINT ["/home/docker/entrypoint.sh"] 64 | CMD ["bash"] 65 | -------------------------------------------------------------------------------- /dockerfiles/push-docker-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ignition:foxy 4 | #docker build --no-cache -t rezenders/ignition:foxy -f ignition/ignition-foxy/Dockerfile ignition/ignition-foxy/ 5 | #docker push rezenders/ignition:foxy 6 | 7 | # ignition:humble 8 | docker build -t rezenders/ignition:humble -f ignition/ignition-humble/Dockerfile ignition/ignition-humble/ 9 | docker push rezenders/ignition:humble 10 | 11 | # ignition:ardusub-foxy 12 | #docker build --no-cache -t rezenders/ignition:ardusub-foxy -f ignition-ardusub/ignition-ardusub-foxy/Dockerfile ignition-ardusub/ignition-ardusub-foxy/ 13 | #docker push rezenders/ignition:ardusub-foxy 14 | 15 | # ignition:ardusub-humble 16 | docker build -t rezenders/ignition:ardusub-humble -f ignition-ardusub/ignition-ardusub-humble/Dockerfile ignition-ardusub/ignition-ardusub-humble/ 17 | docker push rezenders/ignition:ardusub-humble 18 | 19 | # ignition:hackathon-foxy 20 | #docker build --no-cache -t rezenders/ignition:hackathon-foxy -f ignition-hackathon/ignition-hackathon-foxy/Dockerfile ignition-hackathon/ignition-hackathon-foxy/ 21 | #docker push rezenders/ignition:hackathon-foxy 22 | 23 | # ignition:hackathon-humble 24 | docker build -t rezenders/ignition:hackathon-humble -f ignition-hackathon/ignition-hackathon-humble/Dockerfile ignition-hackathon/ignition-hackathon-humble/ 25 | docker push rezenders/ignition:hackathon-humble 26 | 27 | # ignition:hackathon-nvidia-foxy 28 | #docker build --no-cache -t rezenders/ignition:hackathon-nvidia -f ignition-nvidia/Dockerfile ignition-nvidia/ 29 | #docker push rezenders/ignition:hackathon-nvidia 30 | 31 | # ignition:hackathon-nvidia-humble 32 | docker build -t rezenders/ignition:hackathon-nvidia-humble -f ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-humble/Dockerfile ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-humble/ 33 | docker push rezenders/ignition:hackathon-nvidia-humble 34 | 35 | # ignition:hackathon-non-nvidia-foxy 36 | #docker build --no-cache -t rezenders/ignition:hackathon-non-nvidia -f ignition-non-nvidia/Dockerfile ignition-non-nvidia/ 37 | #docker push rezenders/ignition:hackathon-non-nvidia 38 | 39 | # ignition:hackathon-non-nvidia-foxy 40 | docker build -t rezenders/ignition:hackathon-non-nvidia -f ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-humble/Dockerfile ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-humble/ 41 | docker push rezenders/ignition:hackathon-non-nvidia-humble 42 | 43 | #ros-hackathon-foxy 44 | #docker build --no-cache -t rezenders/ros-foxy-hackathon -f ros-foxy-hackathon/Dockerfile ros-foxy-hackathon/ 45 | #docker push rezenders/ros-foxy-hackathon 46 | 47 | #ros-hackathon-humble 48 | docker build -t rezenders/ros-hackathon-humble -f ros-hackathon/ros-hackathon-humble/Dockerfile ros-hackathon/ros-hackathon-humble/ 49 | docker push rezenders/ros-hackathon-humble 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ardusub sitl logs 2 | *.tlog 3 | *.tlog.raw 4 | eeprom.bin 5 | 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | pip-wheel-metadata/ 29 | share/python-wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .nox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *.cover 55 | *.py,cover 56 | .hypothesis/ 57 | .pytest_cache/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | local_settings.py 66 | db.sqlite3 67 | db.sqlite3-journal 68 | 69 | # Flask stuff: 70 | instance/ 71 | .webassets-cache 72 | 73 | # Scrapy stuff: 74 | .scrapy 75 | 76 | # Sphinx documentation 77 | docs/_build/ 78 | 79 | # PyBuilder 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 100 | __pypackages__/ 101 | 102 | # Celery stuff 103 | celerybeat-schedule 104 | celerybeat.pid 105 | 106 | # SageMath parsed files 107 | *.sage.py 108 | 109 | # Environments 110 | .env 111 | .venv 112 | env/ 113 | venv/ 114 | ENV/ 115 | env.bak/ 116 | venv.bak/ 117 | 118 | # Spyder project settings 119 | .spyderproject 120 | .spyproject 121 | 122 | # Rope project settings 123 | .ropeproject 124 | 125 | # mkdocs documentation 126 | /site 127 | 128 | # mypy 129 | .mypy_cache/ 130 | .dmypy.json 131 | dmypy.json 132 | 133 | # Pyre type checker 134 | .pyre/ 135 | 136 | ros1_ws/build/* 137 | ros1_ws/install/* 138 | ros1_ws/devel/* 139 | ros1_ws/logs/* 140 | ros1_ws/site/* 141 | ros1_ws/.catkin_tools/* 142 | 143 | dockerfiles/ros1-2-ignition/ros2_ws/build/* 144 | dockerfiles/ros1-2-ignition/ros2_ws/install/* 145 | dockerfiles/ros1-2-ignition/ros2_ws/log/* 146 | dockerfiles/ros1-2-ignition/ros2_ws/site/* 147 | 148 | *.bag 149 | 150 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros1_ws/src/beginner_tutorials/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | beginner_tutorials 4 | 0.0.0 5 | The beginner_tutorials package 6 | 7 | 8 | 9 | 10 | ros 11 | 12 | 13 | 14 | 15 | 16 | TODO 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | catkin 52 | roscpp 53 | rospy 54 | std_msgs 55 | roscpp 56 | rospy 57 | std_msgs 58 | roscpp 59 | rospy 60 | std_msgs 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros1_ws/src/beginner_tutorials/src/talker.cpp: -------------------------------------------------------------------------------- 1 | #include "ros/ros.h" 2 | #include "std_msgs/String.h" 3 | 4 | #include 5 | 6 | /** 7 | * This tutorial demonstrates simple sending of messages over the ROS system. 8 | */ 9 | int main(int argc, char **argv) 10 | { 11 | /** 12 | * The ros::init() function needs to see argc and argv so that it can perform 13 | * any ROS arguments and name remapping that were provided at the command line. 14 | * For programmatic remappings you can use a different version of init() which takes 15 | * remappings directly, but for most command-line programs, passing argc and argv is 16 | * the easiest way to do it. The third argument to init() is the name of the node. 17 | * 18 | * You must call one of the versions of ros::init() before using any other 19 | * part of the ROS system. 20 | */ 21 | ros::init(argc, argv, "talker"); 22 | 23 | /** 24 | * NodeHandle is the main access point to communications with the ROS system. 25 | * The first NodeHandle constructed will fully initialize this node, and the last 26 | * NodeHandle destructed will close down the node. 27 | */ 28 | ros::NodeHandle n; 29 | 30 | /** 31 | * The advertise() function is how you tell ROS that you want to 32 | * publish on a given topic name. This invokes a call to the ROS 33 | * master node, which keeps a registry of who is publishing and who 34 | * is subscribing. After this advertise() call is made, the master 35 | * node will notify anyone who is trying to subscribe to this topic name, 36 | * and they will in turn negotiate a peer-to-peer connection with this 37 | * node. advertise() returns a Publisher object which allows you to 38 | * publish messages on that topic through a call to publish(). Once 39 | * all copies of the returned Publisher object are destroyed, the topic 40 | * will be automatically unadvertised. 41 | * 42 | * The second parameter to advertise() is the size of the message queue 43 | * used for publishing messages. If messages are published more quickly 44 | * than we can send them, the number here specifies how many messages to 45 | * buffer up before throwing some away. 46 | */ 47 | ros::Publisher chatter_pub = n.advertise("chatter", 1000); 48 | 49 | ros::Rate loop_rate(10); 50 | 51 | /** 52 | * A count of how many messages we have sent. This is used to create 53 | * a unique string for each message. 54 | */ 55 | int count = 0; 56 | while (ros::ok()) 57 | { 58 | /** 59 | * This is a message object. You stuff it with data, and then publish it. 60 | */ 61 | std_msgs::String msg; 62 | 63 | std::stringstream ss; 64 | ss << "hello world " << count; 65 | msg.data = ss.str(); 66 | 67 | ROS_INFO("%s", msg.data.c_str()); 68 | 69 | /** 70 | * The publish() function is how you send messages. The parameter 71 | * is the message object. The type of this object must agree with the type 72 | * given as a template parameter to the advertise<>() call, as was done 73 | * in the constructor above. 74 | */ 75 | chatter_pub.publish(msg); 76 | 77 | ros::spinOnce(); 78 | 79 | loop_rate.sleep(); 80 | ++count; 81 | } 82 | 83 | 84 | return 0; 85 | } -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/README.md: -------------------------------------------------------------------------------- 1 | # ROS2 Workspace for REMARO's hackaton 2 | This template will get you set up using ROS2 in VSCode as your IDE. 3 | It is structured as follows: 4 | ``` 5 | ├──ros1-2-ignition 6 | │ ├──setup-ign-ardupilot-sitl.sh 7 | │ ├──ardupilot 8 | | | └── ... 9 | │ ├──ardupilot_gazebo 10 | | | └── ... 11 | │ ├──ros2_ws # ROS Foxy workspace 12 | | | ├── src 13 | | | | ├──bluerov2_ignition # Code for Bluerov2 simulation in Ignition 14 | | | | ├──remaro_worlds # Ignition simulated environments 15 | | | | └── ... 16 | │ | └── ... 17 | │ └── ... 18 | └── ... 19 | ``` 20 | 21 | Note that ardupilot, bluerov2_ignition and remaro_worlds are included in this repository as git submodules. 22 | 23 | ## Some things to keep in mind 24 | 25 | ### Shortcuts 26 | ROS need sourcing of its setup files. Since we have both ROS1 and 2, we need to source the ROS versions that we are using (usually ROS2). Some shortcuts are defined in the .bashrc file for convenience. They are listed here: 27 | - `sf`: as in source foxy, resolves to 'source /opt/ros/foxy/setup.bash' 28 | - `sn`: as in source noetic, resolves to 'source /opt/ros/noetic/setup.bash' 29 | - `s`: as in source (local), resolves to 'source install/setup.bash' to source local environment in ROS2 30 | - `m`: as in make, resolves to 'bash build.sh', requires a build script to be present in the local directory 31 | 32 | In this hackaton, you will source ROS2 (foxy), and therefore type `sf` and `s`. Note that `s` must be run from `ros2_ws` directory. 33 | 34 | Now, let's get hands-on! 35 | 36 | # Install everything that is necessary 37 | 38 | - Install docker on your machine. You can find instructions [here](https://docs.docker.com/engine/install/ubuntu/) 39 | - Allow non-root users to manage docker. Instructions [here](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) 40 | - Install VSCode. Instructions [here](https://code.visualstudio.com/download) 41 | 42 | # Open the container in vscode 43 | - Clone the hackaton's repo in your computer: 44 | ```Bash 45 | $ git clone https://github.com/remaro-network/tudelft_hackathon.git 46 | ``` 47 | - Go to the folder containing this Dev container (i.e. ros1-2-ignition folder) 48 | - Open it from VSCode (File->Open Folder). 49 | - click on the little green square in the bottom left corner, which should bring up the container dialog 50 | 51 | ![template_vscode_bottom](https://user-images.githubusercontent.com/6098197/91332638-5d47b780-e781-11ea-9fb6-4d134dbfc464.png) 52 | 53 | - In the dialog, select "Remote Containers: Reopen in container" 54 | 55 | VSCode will build the dockerfile inside of `.devcontainer` for you. If you open a terminal inside VSCode (Terminal->New Terminal), you should see that your username has been changed to `ros`, and the bottom left green corner should say "Dev Container" 56 | 57 | ![template_container](https://user-images.githubusercontent.com/6098197/91332895-adbf1500-e781-11ea-8afc-7a22a5340d4a.png) 58 | 59 | - If you want to work in your docker container from terminator (which I strongly recommend), type `terminator` in the VSCode terminal. 60 | 61 | # Test that everything is working! 62 | 63 | Run Ardupilot with software in the loop (SITL): 64 | ``` 65 | $ sim_vehicle.py -L RATBeach -v ArduSub --model=JSON --out=udp:0.0.0.0:14550 --console 66 | ``` 67 | In another terminal (in terminator you can use ctrl+shit+e to split the terminal vertically) run: 68 | ``` 69 | $ ros2 launch tudelft_hackathon bluerov_bringup.launch.py simulation:=true 70 | ``` 71 | -------------------------------------------------------------------------------- /launch/bluerov_record.launch.py: -------------------------------------------------------------------------------- 1 | from launch_ros.actions import Node 2 | from launch import LaunchDescription 3 | from launch.actions import DeclareLaunchArgument, ExecuteProcess 4 | from launch.conditions import IfCondition, UnlessCondition 5 | from launch.substitutions import LaunchConfiguration, PythonExpression 6 | 7 | def generate_launch_description(): 8 | simulation_arg = LaunchConfiguration('simulation') 9 | fcu_url_arg = LaunchConfiguration('fcu_url') 10 | gcs_url_arg = LaunchConfiguration('gcs_url') 11 | system_id_arg = LaunchConfiguration('system_id') 12 | component_id_arg = LaunchConfiguration('component_id') 13 | tgt_system_arg = LaunchConfiguration('target_system_id') 14 | tgt_component_arg = LaunchConfiguration('target_component_id') 15 | 16 | simulation_arg = DeclareLaunchArgument( 17 | 'simulation', 18 | default_value='false' 19 | ) 20 | 21 | gcs_url_arg = DeclareLaunchArgument( 22 | 'gcs_url', 23 | default_value='udp://@localhost:14550' 24 | ) 25 | 26 | system_id_arg = DeclareLaunchArgument( 27 | 'system_id', 28 | default_value='255' 29 | ) 30 | 31 | component_id_arg = DeclareLaunchArgument( 32 | 'component_id', 33 | default_value='240' 34 | ) 35 | 36 | tgt_system_arg = DeclareLaunchArgument( 37 | 'target_system_id', 38 | default_value='1' 39 | ) 40 | 41 | tgt_component_arg = DeclareLaunchArgument( 42 | 'target_component_id', 43 | default_value='1' 44 | ) 45 | 46 | mavros_node = Node( 47 | package='mavros', 48 | executable='mavros_node', 49 | parameters=[{ 50 | 'fcu_url': LaunchConfiguration('fcu_url'), 51 | 'gcs_url': LaunchConfiguration('gcs_url'), 52 | 'system_id': LaunchConfiguration('system_id'), 53 | 'component_id': LaunchConfiguration('component_id'), 54 | 'target_system_id': LaunchConfiguration('target_system_id'), 55 | 'target_component_id': LaunchConfiguration('target_component_id'), 56 | }] 57 | ) 58 | 59 | ping_360_node = Node( 60 | package='ping360_sonar', 61 | executable='ping360_node', 62 | parameters=[{ 63 | 'connection_type': 'udp', 64 | 'udp_address': '192.168.2.2', 65 | 'udp_port': 9092, 66 | 'fallback_emulated': False, 67 | 'publish_eco': True, 68 | 'publish_scan': True, 69 | 'publish_image': True, 70 | }], 71 | ) 72 | 73 | agent_node = Node( 74 | package='tudelft_hackathon', 75 | executable='bluerov_agent.py', 76 | output='screen' 77 | ) 78 | 79 | return LaunchDescription([ 80 | simulation_arg, 81 | gcs_url_arg, 82 | system_id_arg, 83 | component_id_arg, 84 | tgt_system_arg, 85 | tgt_component_arg, 86 | # Real robot 87 | DeclareLaunchArgument( 88 | 'fcu_url', 89 | default_value='udp://192.168.2.1:14550@192.168.2.2:14555', 90 | condition=UnlessCondition(LaunchConfiguration('simulation')) 91 | ), 92 | # # Simulation 93 | DeclareLaunchArgument( 94 | 'fcu_url', 95 | default_value='udp://:14551@:14555', 96 | condition=IfCondition(LaunchConfiguration('simulation')) 97 | ), 98 | mavros_node, 99 | ping_360_node, 100 | ExecuteProcess( 101 | cmd=['ros2', 'bag', 'record', '-a'], 102 | output='screen' 103 | ) 104 | ]) 105 | -------------------------------------------------------------------------------- /PARTICIPANTS_TODO.md: -------------------------------------------------------------------------------- 1 | # Activities to be done before the hackathon: 2 | 3 | #### Follow basic ROS2 tutorials: 4 | * [Beginner: CLI Tools](https://docs.ros.org/en/foxy/Tutorials.html#beginner-cli-tools) 5 | - [Configuring your ROS 2 environment](https://docs.ros.org/en/foxy/Tutorials/Configuring-ROS2-Environment.html) 6 | - [Understanding ROS 2 nodes](https://docs.ros.org/en/foxy/Tutorials/Understanding-ROS2-Nodes.html) 7 | - [Understanding ROS 2 topics](https://docs.ros.org/en/foxy/Tutorials/Topics/Understanding-ROS2-Topics.html) 8 | - [Understanding ROS 2 services](https://docs.ros.org/en/foxy/Tutorials/Services/Understanding-ROS2-Services.html) 9 | - [Understanding ROS 2 parameters](https://docs.ros.org/en/foxy/Tutorials/Parameters/Understanding-ROS2-Parameters.html) 10 | - [Introducing ROS 2 launch](https://docs.ros.org/en/foxy/Tutorials/Launch/CLI-Intro.html) 11 | - [Recording and playing back data](https://docs.ros.org/en/foxy/Tutorials/Ros2bag/Recording-And-Playing-Back-Data.html) 12 | * [Beginner: Client Libraries](https://docs.ros.org/en/foxy/Tutorials.html#beginner-client-libraries) 13 | - [Creating a workspace](https://docs.ros.org/en/foxy/Tutorials/Workspace/Creating-A-Workspace.html) 14 | - [Creating your first ROS 2 package](https://docs.ros.org/en/foxy/Tutorials/Creating-Your-First-ROS2-Package.html) 15 | - [Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/foxy/Tutorials/Writing-A-Simple-Py-Publisher-And-Subscriber.html) 16 | - [Writing a simple service and client (Python)](https://docs.ros.org/en/foxy/Tutorials/Writing-A-Simple-Py-Service-And-Client.html) 17 | 18 | #### Follow basic Ignition tutorials 19 | * [Setting-up a Robot Simulation (Ignition Gazebo)](https://docs.ros.org/en/foxy/Tutorials/Simulators/Ignition/Setting-up-a-Robot-Simulation-Ignition.html) 20 | 21 | #### Install ROS2 workspace for the hackathon locally, or run the docker image beforehand to make sure it is working 22 | 23 | Read [this](https://github.com/remaro-network/tudelft_hackathon#installation) first 24 | 25 | * [Install locally instructions](https://github.com/remaro-network/tudelft_hackathon#install-locally) 26 | * Docker: 27 | - [Install Docker prereqs](https://github.com/remaro-network/tudelft_hackathon#install-prerequisites-to-run-with-docker) 28 | - [Docker CLI instructions](https://github.com/remaro-network/tudelft_hackathon#run-it-with-docker-via-cli) 29 | - [Docker with VSCode instructions](https://github.com/remaro-network/tudelft_hackathon#run-it-with-docker-with-vscode) 30 | 31 | **Bugs:** If you find bugs, please open an Issue with a detailed explanation of the problem, or message @rezenders. 32 | 33 | #### For the more interested participants, reproduce everything and suggest how to improve the training 34 | 35 | * For this, it is strongly recommend to do so by opening issues and pull requests 36 | * There are some issues already open. That is a good starting point 37 | 38 | # Activities to be done during hackathon: 39 | 40 | #### Run bluerov agent 41 | 42 | * Run the bluerov agent both in the real BlueROV2 and in Gazebo (Ignition) 43 | * Complete the [potential_avoidance]((https://github.com/remaro-network/tudelft_hackathon/blob/ros2/scripts/potential_avoidance.py) code and run it both in the real BlueROV2 and Gazebo (Ignition). Issue [#36](https://github.com/remaro-network/tudelft_hackathon/issues/36). 44 | 45 | #### Improve the system 46 | Suggestions: 47 | * Issues marked with `hackathon_task` label. You can find them in this [project tab](https://github.com/remaro-network/tudelft_hackathon/projects/2) 48 | * Better avoidance algorithm 49 | * Adjust velocity parameters and sonar "field-of-view" 50 | * More elaborated world 51 | * Improve launch files 52 | * Improve formatting 53 | * Improve documentation 54 | * Add tests 55 | -------------------------------------------------------------------------------- /launch/bluerov_bringup_no_ign.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | 5 | from launch_ros.actions import Node 6 | from launch import LaunchDescription 7 | from launch.actions import DeclareLaunchArgument 8 | from launch.actions import IncludeLaunchDescription 9 | from launch.conditions import IfCondition, UnlessCondition 10 | from launch.substitutions import LaunchConfiguration, PythonExpression 11 | from launch.launch_description_sources import PythonLaunchDescriptionSource 12 | 13 | 14 | def generate_launch_description(): 15 | simulation_arg = LaunchConfiguration('simulation') 16 | fcu_url_arg = LaunchConfiguration('fcu_url') 17 | gcs_url_arg = LaunchConfiguration('gcs_url') 18 | system_id_arg = LaunchConfiguration('system_id') 19 | component_id_arg = LaunchConfiguration('component_id') 20 | tgt_system_arg = LaunchConfiguration('target_system_id') 21 | tgt_component_arg = LaunchConfiguration('target_component_id') 22 | 23 | simulation_arg = DeclareLaunchArgument( 24 | 'simulation', 25 | default_value='true' 26 | ) 27 | 28 | gcs_url_arg = DeclareLaunchArgument( 29 | 'gcs_url', 30 | default_value='udp://@localhost:14550' 31 | ) 32 | 33 | system_id_arg = DeclareLaunchArgument( 34 | 'system_id', 35 | default_value='255' 36 | ) 37 | 38 | component_id_arg = DeclareLaunchArgument( 39 | 'component_id', 40 | default_value='240' 41 | ) 42 | 43 | tgt_system_arg = DeclareLaunchArgument( 44 | 'target_system_id', 45 | default_value='1' 46 | ) 47 | 48 | tgt_component_arg = DeclareLaunchArgument( 49 | 'target_component_id', 50 | default_value='1' 51 | ) 52 | 53 | mavros_node = Node( 54 | package='mavros', 55 | executable='mavros_node', 56 | parameters=[{ 57 | 'fcu_url': LaunchConfiguration('fcu_url'), 58 | 'gcs_url': LaunchConfiguration('gcs_url'), 59 | 'system_id': LaunchConfiguration('system_id'), 60 | 'component_id': LaunchConfiguration('component_id'), 61 | 'target_system_id': LaunchConfiguration('target_system_id'), 62 | 'target_component_id': LaunchConfiguration('target_component_id'), 63 | }] 64 | ) 65 | 66 | agent_node = Node( 67 | package='tudelft_hackathon', 68 | executable='potential_avoidance.py', 69 | output='screen' 70 | ) 71 | 72 | return LaunchDescription([ 73 | simulation_arg, 74 | gcs_url_arg, 75 | system_id_arg, 76 | component_id_arg, 77 | tgt_system_arg, 78 | tgt_component_arg, 79 | # Real robot 80 | DeclareLaunchArgument( 81 | 'fcu_url', 82 | default_value='udp://192.168.2.1:14550@192.168.2.2:14555', 83 | condition=UnlessCondition(LaunchConfiguration('simulation')) 84 | ), 85 | # Simulation 86 | DeclareLaunchArgument( 87 | 'fcu_url', 88 | default_value='udp://:14551@:14555', 89 | condition=IfCondition(LaunchConfiguration('simulation')) 90 | ), 91 | mavros_node, 92 | Node( 93 | package='ping360_sonar', 94 | executable='ping360_node', 95 | parameters=[{ 96 | 'connection_type': 'udp', 97 | 'udp_address': '192.168.2.2', 98 | 'udp_port': 9092, 99 | 'fallback_emulated': False, 100 | 'publish_echo': True, 101 | 'publish_scan': True, 102 | 'publish_image': True, 103 | }], 104 | condition=UnlessCondition(LaunchConfiguration('simulation')) 105 | ), 106 | agent_node, 107 | ]) 108 | -------------------------------------------------------------------------------- /.github/workflows/container.yaml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # GitHub recommends pinning actions to a commit SHA. 7 | # To get a newer version, you will need to update the SHA. 8 | # You can also reference a tag or branch, but the action may change without warning. 9 | 10 | name: Docker Images 11 | 12 | on: 13 | push: 14 | branches: 15 | - ros2 16 | tags: 17 | - 'v*' 18 | 19 | env: 20 | REGISTRY: ghcr.io 21 | IMAGE_NAME: ${{ github.repository }} 22 | 23 | jobs: 24 | build-and-push-image: 25 | runs-on: ubuntu-latest 26 | permissions: 27 | contents: read 28 | packages: write 29 | 30 | steps: 31 | - name: Checkout repository 32 | uses: actions/checkout@v3 33 | 34 | - name: Log in to the Container registry 35 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 36 | with: 37 | registry: ${{ env.REGISTRY }} 38 | username: ${{ github.actor }} 39 | password: ${{ secrets.GITHUB_TOKEN }} 40 | 41 | - name: Extract metadata (tags, labels) for Docker 42 | id: meta 43 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 44 | with: 45 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 46 | tags: | 47 | type=ref,event=branch 48 | type=ref,event=pr 49 | type=semver,pattern={{version}} 50 | type=semver,pattern={{major}}.{{minor}} 51 | 52 | - name: Build and push gazebo garden image with ros humble 53 | uses: docker/build-push-action@v4 54 | with: 55 | context: dockerfiles/ignition/ignition-humble/ 56 | push: true 57 | tags: ${{ env.REGISTRY }}/remaro-network/ignition-humble:latest 58 | labels: latest 59 | 60 | - name: Build and push ignition-ardusub-humble image 61 | uses: docker/build-push-action@v4 62 | with: 63 | context: dockerfiles/ignition-ardusub/ignition-ardusub-humble/ 64 | push: true 65 | build-args: BASE_IMAGE=${{ env.REGISTRY }}/remaro-network/ignition-humble:latest 66 | tags: ${{ env.REGISTRY }}/remaro-network/ignition-ardusub-humble:latest 67 | 68 | - name: Build and push ignition hackathon image 69 | uses: docker/build-push-action@v4 70 | with: 71 | context: dockerfiles/ignition-hackathon/ignition-hackathon-humble/ 72 | push: true 73 | tags: ${{ env.REGISTRY }}/remaro-network/tudelft_hackathon_base:latest 74 | # tags: ${{ steps.meta.outputs.tags }} 75 | # labels: ${{ steps.meta.outputs.labels }} 76 | build-args: BASE_IMAGE=${{ env.REGISTRY }}/remaro-network/ignition-ardusub-humble:latest 77 | 78 | - name: Build and push ignition hackathon non nvidia image 79 | uses: docker/build-push-action@v4 80 | with: 81 | context: dockerfiles/ignition-hackathon-gpus/ignition-hackathon-non-nvidia/ignition-hackathon-non-nvidia-humble/ 82 | push: true 83 | tags: ${{ env.REGISTRY }}/remaro-network/tudelft_hackathon:non-nvidia 84 | build-args: BASE_IMAGE=${{ env.REGISTRY }}/remaro-network/tudelft_hackathon_base:latest 85 | 86 | - name: Build and push ignition hackathon nvidia image 87 | uses: docker/build-push-action@v4 88 | with: 89 | context: dockerfiles/ignition-hackathon-gpus/ignition-hackathon-nvidia/ignition-hackathon-nvidia-humble/ 90 | push: true 91 | # tags: ${{ steps.meta.outputs.tags }} 92 | # labels: ${{ steps.meta.outputs.labels }} 93 | tags: ${{ env.REGISTRY }}/remaro-network/tudelft_hackathon:nvidia 94 | build-args: BASE_IMAGE=${{ env.REGISTRY }}/remaro-network/tudelft_hackathon_base:latest 95 | -------------------------------------------------------------------------------- /launch/bluerov_bringup.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | 5 | from launch_ros.actions import Node 6 | from launch import LaunchDescription 7 | from launch.actions import DeclareLaunchArgument 8 | from launch.actions import IncludeLaunchDescription 9 | from launch.conditions import IfCondition, UnlessCondition 10 | from launch.substitutions import LaunchConfiguration, PythonExpression 11 | from launch.launch_description_sources import AnyLaunchDescriptionSource 12 | from launch.launch_description_sources import PythonLaunchDescriptionSource 13 | 14 | 15 | def generate_launch_description(): 16 | pkg_tudelft_hackathon = get_package_share_directory('tudelft_hackathon') 17 | 18 | simulation_arg = LaunchConfiguration('simulation') 19 | fcu_url_arg = LaunchConfiguration('fcu_url') 20 | gcs_url_arg = LaunchConfiguration('gcs_url') 21 | tgt_system_arg = LaunchConfiguration('target_system_id') 22 | tgt_component_arg = LaunchConfiguration('target_component_id') 23 | 24 | simulation_arg = DeclareLaunchArgument( 25 | 'simulation', 26 | default_value='true' 27 | ) 28 | 29 | gcs_url_arg = DeclareLaunchArgument( 30 | 'gcs_url', 31 | default_value='udp://@localhost:14550' 32 | ) 33 | 34 | tgt_system_arg = DeclareLaunchArgument( 35 | 'tgt_system', 36 | default_value='1' 37 | ) 38 | 39 | tgt_component_arg = DeclareLaunchArgument( 40 | 'tgt_component', 41 | default_value='1' 42 | ) 43 | 44 | mavros_path = get_package_share_directory('mavros') 45 | mavros_launch_path = os.path.join( 46 | mavros_path, 'launch', 'node.launch') 47 | hackathon_apm_config_path = os.path.join( 48 | pkg_tudelft_hackathon, 'launch', 'apm_config.yaml') 49 | hackathon_apm_plugin_path = os.path.join( 50 | pkg_tudelft_hackathon, 'launch', 'apm_pluginlists.yaml') 51 | mavros_node = IncludeLaunchDescription( 52 | AnyLaunchDescriptionSource(mavros_launch_path), 53 | launch_arguments={ 54 | 'fcu_url': LaunchConfiguration('fcu_url'), 55 | 'gcs_url': LaunchConfiguration('gcs_url'), 56 | 'tgt_system': LaunchConfiguration('tgt_system'), 57 | 'tgt_component': LaunchConfiguration('tgt_component'), 58 | 'config_yaml': hackathon_apm_config_path, 59 | 'pluginlists_yaml': hackathon_apm_plugin_path, 60 | }.items() 61 | ) 62 | 63 | agent_node = Node( 64 | package='tudelft_hackathon', 65 | executable='random_wall_avoidance.py', 66 | output='screen' 67 | ) 68 | 69 | return LaunchDescription([ 70 | simulation_arg, 71 | gcs_url_arg, 72 | tgt_system_arg, 73 | tgt_component_arg, 74 | # Real robot 75 | DeclareLaunchArgument( 76 | 'fcu_url', 77 | default_value='udp://192.168.2.1:14550@192.168.2.2:14555', 78 | condition=UnlessCondition(LaunchConfiguration('simulation')) 79 | ), 80 | # Simulation 81 | DeclareLaunchArgument( 82 | 'fcu_url', 83 | default_value='udp://:14551@:14555', 84 | condition=IfCondition(LaunchConfiguration('simulation')) 85 | ), 86 | IncludeLaunchDescription( 87 | PythonLaunchDescriptionSource( 88 | os.path.join(pkg_tudelft_hackathon, 89 | 'launch', 90 | 'bluerov_ign_sim.launch.py')), 91 | condition=IfCondition(LaunchConfiguration('simulation')) 92 | ), 93 | mavros_node, 94 | Node( 95 | package='ping360_sonar', 96 | executable='ping360_node', 97 | parameters=[{ 98 | 'angle_sector': 90, 99 | 'connection_type': 'udp', 100 | 'udp_address': '192.168.2.2', 101 | 'udp_port': 9092, 102 | 'fallback_emulated': False, 103 | 'publish_echo': True, 104 | 'publish_scan': True, 105 | 'publish_image': True, 106 | }], 107 | condition=UnlessCondition(LaunchConfiguration('simulation')) 108 | ), 109 | agent_node, 110 | ]) 111 | -------------------------------------------------------------------------------- /scripts/potential_avoidance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import rclpy 4 | import random 5 | import threading 6 | import numpy as np 7 | 8 | from rclpy.node import Node 9 | 10 | from sensor_msgs.msg import LaserScan 11 | from mavros_wrapper.ardusub_wrapper import * 12 | 13 | def laser_scan_cb(msg, ardusub): 14 | forward_speed = 1 # Maximum forward velocity 15 | 16 | # TODO: Do something with the sonar msg in order to make the robot not 17 | # crash into the walls 18 | # 19 | # CHEAT: 20 | # LaserScan msg definition can be found here: https://docs.ros2.org/latest/api/sensor_msgs/msg/LaserScan.html 21 | # Before checking the solution provided, check this example: 22 | # https://github.com/gazebosim/docs/blob/master/citadel/sensors.md#avoid-the-wall 23 | 24 | # Compute the potential vector 25 | sonar_data = msg 26 | angles = np.linspace(sonar_data.angle_min, sonar_data.angle_max, num=len(sonar_data.ranges)) 27 | potentials_x = np.multiply(1/np.asarray(sonar_data.ranges)**2, np.cos(angles)) 28 | sum_potentials_x = np.sum(potentials_x) 29 | 30 | print("angle_min: ", sonar_data.angle_min) 31 | print("angle_max: ", sonar_data.angle_max) 32 | print("Angles: ", angles) 33 | 34 | sum_potentials_angles = np.sum(np.cos(angles)) 35 | print("Sum of Cosine of Angles: ", sum_potentials_angles) 36 | 37 | potentials_y = np.multiply(1/np.asarray(sonar_data.ranges)**2, np.sin(angles)) 38 | sum_potentials_y = np.sum(potentials_y) 39 | 40 | p = (sum_potentials_x,sum_potentials_y) 41 | 42 | # set some gains 43 | k_p = 1/sum_potentials_angles 44 | # k_p = 1/sum_potentials_x 45 | k_phi = -2 46 | 47 | # Function for computing the new velocity vector 48 | potential_velocity(forward_speed,(p),k_p,k_phi) 49 | 50 | def potential_velocity(max_vel,p,K_p,K_phi): 51 | """ 52 | This function sends velocity commands to ardusub according to 53 | the maximum velocity set for the robot 54 | and a potential repulsive field generated by an obstacle 55 | Parameters: 56 | 57 | -max_vel: maximum forward velocity (without obstacles) 58 | -p: (px,py) values generated by the potential field in the x and y axis, respectively 59 | -K_p: gain that regulates linear velocity 60 | -K_phi: gain that regulates angular velocity 61 | 62 | """ 63 | p_x,p_y = p 64 | forward_vel = max_vel - K_p * p_x 65 | # compute the angle between linear velocity and vy generated by potential obstacles 66 | yaw_vel = K_phi*np.arctan(float(- K_p * p_y/forward_vel)) 67 | 68 | # Write velocities in channels 69 | # The previous values should be between -1 and 1. 70 | ardusub.toogle_rc_override(True) # start overriding RC 71 | ardusub.set_rc_override_channels(forward=forward_vel, yaw = yaw_vel) # set values to override 72 | print("forward_vel : ",forward_vel) 73 | print("yaw_vel : ",yaw_vel) 74 | print("kp : ",K_p) 75 | 76 | if __name__ == '__main__': 77 | print("Starting wall avoidance. Let's swim!") 78 | 79 | # Initialize ros node 80 | rclpy.init(args=sys.argv) 81 | 82 | ardusub = BlueROVArduSubWrapper("ardusub_node") 83 | 84 | thread = threading.Thread(target=rclpy.spin, args=(ardusub, ), daemon=True) 85 | thread.start() 86 | 87 | # TODO: Set flight mode to MANUAL, STABILIZE or DEPTH HOLD 88 | service_timer = ardusub.create_rate(2) 89 | while ardusub.status.mode != "ALT_HOLD": 90 | ardusub.set_mode("ALT_HOLD") 91 | service_timer.sleep() 92 | print("Manual mode selected") 93 | 94 | # TODO: Arm motors 95 | while ardusub.status.armed == False: 96 | ardusub.arm_motors(True) 97 | service_timer.sleep() 98 | 99 | print("Thrusters armed") 100 | 101 | print("Initializing mission") 102 | 103 | # TODO: start publishing on /mavros/rc/override 104 | ardusub.toogle_rc_override(True) 105 | ardusub.set_rc_override_channels(throttle=0.0, pitch=0.0, forward=0.01) 106 | # TODO: start moving forward 107 | 108 | # Sonar subscriber 109 | laser_subscriber = ardusub.create_subscription( 110 | LaserScan, '/scan', (lambda msg: laser_scan_cb(msg, ardusub)), 20) 111 | 112 | rate = ardusub.create_rate(2) 113 | try: 114 | while rclpy.ok(): 115 | rate.sleep() 116 | except KeyboardInterrupt: 117 | pass 118 | ardusub.arm_motors(False) # better safe than sorry 119 | ardusub.destroy_node() 120 | rclpy.shutdown() 121 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 8, 3 | "editor.rulers": [ 4 | 100 5 | ], 6 | "files.associations": { 7 | "*.inc": "php", 8 | "*.repos": "yaml", 9 | "*.world": "xml", 10 | "*.xacro": "xml", 11 | "cctype": "cpp", 12 | "clocale": "cpp", 13 | "cmath": "cpp", 14 | "csignal": "cpp", 15 | "cstdarg": "cpp", 16 | "cstddef": "cpp", 17 | "cstdio": "cpp", 18 | "cstdlib": "cpp", 19 | "cstring": "cpp", 20 | "ctime": "cpp", 21 | "cwchar": "cpp", 22 | "cwctype": "cpp", 23 | "array": "cpp", 24 | "atomic": "cpp", 25 | "strstream": "cpp", 26 | "bit": "cpp", 27 | "*.tcc": "cpp", 28 | "bitset": "cpp", 29 | "chrono": "cpp", 30 | "complex": "cpp", 31 | "condition_variable": "cpp", 32 | "cstdint": "cpp", 33 | "deque": "cpp", 34 | "list": "cpp", 35 | "map": "cpp", 36 | "set": "cpp", 37 | "unordered_map": "cpp", 38 | "vector": "cpp", 39 | "exception": "cpp", 40 | "algorithm": "cpp", 41 | "functional": "cpp", 42 | "iterator": "cpp", 43 | "memory": "cpp", 44 | "memory_resource": "cpp", 45 | "numeric": "cpp", 46 | "optional": "cpp", 47 | "random": "cpp", 48 | "ratio": "cpp", 49 | "string": "cpp", 50 | "string_view": "cpp", 51 | "system_error": "cpp", 52 | "tuple": "cpp", 53 | "type_traits": "cpp", 54 | "utility": "cpp", 55 | "fstream": "cpp", 56 | "future": "cpp", 57 | "initializer_list": "cpp", 58 | "iomanip": "cpp", 59 | "iosfwd": "cpp", 60 | "iostream": "cpp", 61 | "istream": "cpp", 62 | "limits": "cpp", 63 | "mutex": "cpp", 64 | "new": "cpp", 65 | "ostream": "cpp", 66 | "shared_mutex": "cpp", 67 | "sstream": "cpp", 68 | "stdexcept": "cpp", 69 | "streambuf": "cpp", 70 | "thread": "cpp", 71 | "cfenv": "cpp", 72 | "cinttypes": "cpp", 73 | "typeindex": "cpp", 74 | "typeinfo": "cpp", 75 | "variant": "cpp", 76 | "csetjmp": "cpp", 77 | "codecvt": "cpp", 78 | "unordered_set": "cpp", 79 | "regex": "cpp", 80 | "hash_map": "cpp", 81 | "hash_set": "cpp", 82 | "slist": "cpp", 83 | "scoped_allocator": "cpp", 84 | "valarray": "cpp" 85 | }, 86 | "python.analysis.extraPaths": [ 87 | "/opt/ros/foxy/lib/python3.8/site-packages/" 88 | ], 89 | // Autocomplete from ros python packages 90 | "python.autoComplete.extraPaths": [ 91 | "/opt/ros/foxy/lib/python3.8/site-packages/" 92 | ], 93 | // Environment file lets vscode find python files within workspace 94 | "python.envFile": "${workspaceFolder}/.env", 95 | // Use the system installed version of autopep8 96 | "python.formatting.autopep8Path": "/usr/bin/autopep8", 97 | "python.formatting.autopep8Args": [ 98 | "--max-line-length=100" 99 | ], 100 | "C_Cpp.default.intelliSenseMode": "clang-x64", 101 | "C_Cpp.formatting": "Disabled", 102 | "uncrustify.configPath.linux": "/opt/ros/foxy/lib/python3.8/site-packages/ament_uncrustify/configuration/ament_code_style.cfg", 103 | "[cpp]": { 104 | "editor.defaultFormatter": "zachflower.uncrustify" 105 | }, 106 | "search.exclude": { 107 | "**/node_modules": true, 108 | "**/bower_components": true, 109 | "**/*.code-search": true, 110 | "**/build": true, 111 | "**/install": true, 112 | "**/log": true 113 | }, 114 | "cSpell.words": [ 115 | "athackst", 116 | "autopep", 117 | "cmake", 118 | "cppcheck", 119 | "cpplint", 120 | "DCMAKE", 121 | "deque", 122 | "devcontainer", 123 | "ints", 124 | "noqa", 125 | "pytest", 126 | "rclcpp", 127 | "rclpy", 128 | "repos", 129 | "rosdep", 130 | "rosdistro", 131 | "rosidl", 132 | "RTPS", 133 | "uncrustify", 134 | "Wextra", 135 | "Wpedantic", 136 | "xmllint" 137 | ], 138 | "cSpell.allowCompoundWords": true, 139 | "cSpell.ignorePaths": [ 140 | "**/package-lock.json", 141 | "**/node_modules/**", 142 | "**/vscode-extension/**", 143 | "**/.git/objects/**", 144 | ".vscode", 145 | ".vscode-insiders", 146 | ".devcontainer/devcontainer.json" 147 | ], 148 | "ros.distro": "noetic", 149 | } -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/ros1_ws/src/beginner_tutorials/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(beginner_tutorials) 3 | 4 | ## Compile as C++11, supported in ROS Kinetic and newer 5 | # add_compile_options(-std=c++11) 6 | 7 | ## Find catkin macros and libraries 8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) 9 | ## is used, also find other catkin packages 10 | find_package(catkin REQUIRED COMPONENTS 11 | roscpp 12 | rospy 13 | std_msgs 14 | ) 15 | 16 | ## System dependencies are found with CMake's conventions 17 | # find_package(Boost REQUIRED COMPONENTS system) 18 | 19 | 20 | ## Uncomment this if the package has a setup.py. This macro ensures 21 | ## modules and global scripts declared therein get installed 22 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html 23 | # catkin_python_setup() 24 | 25 | ################################################ 26 | ## Declare ROS messages, services and actions ## 27 | ################################################ 28 | 29 | ## To declare and build messages, services or actions from within this 30 | ## package, follow these steps: 31 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in 32 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). 33 | ## * In the file package.xml: 34 | ## * add a build_depend tag for "message_generation" 35 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET 36 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in 37 | ## but can be declared for certainty nonetheless: 38 | ## * add a exec_depend tag for "message_runtime" 39 | ## * In this file (CMakeLists.txt): 40 | ## * add "message_generation" and every package in MSG_DEP_SET to 41 | ## find_package(catkin REQUIRED COMPONENTS ...) 42 | ## * add "message_runtime" and every package in MSG_DEP_SET to 43 | ## catkin_package(CATKIN_DEPENDS ...) 44 | ## * uncomment the add_*_files sections below as needed 45 | ## and list every .msg/.srv/.action file to be processed 46 | ## * uncomment the generate_messages entry below 47 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) 48 | 49 | ## Generate messages in the 'msg' folder 50 | # add_message_files( 51 | # FILES 52 | # Message1.msg 53 | # Message2.msg 54 | # ) 55 | 56 | ## Generate services in the 'srv' folder 57 | # add_service_files( 58 | # FILES 59 | # Service1.srv 60 | # Service2.srv 61 | # ) 62 | 63 | ## Generate actions in the 'action' folder 64 | # add_action_files( 65 | # FILES 66 | # Action1.action 67 | # Action2.action 68 | # ) 69 | 70 | ## Generate added messages and services with any dependencies listed here 71 | # generate_messages( 72 | # DEPENDENCIES 73 | # std_msgs 74 | # ) 75 | 76 | ################################################ 77 | ## Declare ROS dynamic reconfigure parameters ## 78 | ################################################ 79 | 80 | ## To declare and build dynamic reconfigure parameters within this 81 | ## package, follow these steps: 82 | ## * In the file package.xml: 83 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" 84 | ## * In this file (CMakeLists.txt): 85 | ## * add "dynamic_reconfigure" to 86 | ## find_package(catkin REQUIRED COMPONENTS ...) 87 | ## * uncomment the "generate_dynamic_reconfigure_options" section below 88 | ## and list every .cfg file to be processed 89 | 90 | ## Generate dynamic reconfigure parameters in the 'cfg' folder 91 | # generate_dynamic_reconfigure_options( 92 | # cfg/DynReconf1.cfg 93 | # cfg/DynReconf2.cfg 94 | # ) 95 | 96 | ################################### 97 | ## catkin specific configuration ## 98 | ################################### 99 | ## The catkin_package macro generates cmake config files for your package 100 | ## Declare things to be passed to dependent projects 101 | ## INCLUDE_DIRS: uncomment this if your package contains header files 102 | ## LIBRARIES: libraries you create in this project that dependent projects also need 103 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need 104 | ## DEPENDS: system dependencies of this project that dependent projects also need 105 | catkin_package( 106 | # INCLUDE_DIRS include 107 | # LIBRARIES beginner_tutorials 108 | # CATKIN_DEPENDS roscpp rospy std_msgs 109 | # DEPENDS system_lib 110 | ) 111 | 112 | ########### 113 | ## Build ## 114 | ########### 115 | 116 | ## Specify additional locations of header files 117 | ## Your package locations should be listed before other locations 118 | include_directories( 119 | # include 120 | ${catkin_INCLUDE_DIRS} 121 | ) 122 | 123 | ## Declare a C++ library 124 | # add_library(${PROJECT_NAME} 125 | # src/${PROJECT_NAME}/beginner_tutorials.cpp 126 | # ) 127 | 128 | ## Add cmake target dependencies of the library 129 | ## as an example, code may need to be generated before libraries 130 | ## either from message generation or dynamic reconfigure 131 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 132 | 133 | ## Declare a C++ executable 134 | ## With catkin_make all packages are built within a single CMake context 135 | ## The recommended prefix ensures that target names across packages don't collide 136 | # add_executable(${PROJECT_NAME}_node src/beginner_tutorials_node.cpp) 137 | 138 | ## Rename C++ executable without prefix 139 | ## The above recommended prefix causes long target names, the following renames the 140 | ## target back to the shorter version for ease of user use 141 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" 142 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") 143 | 144 | ## Add cmake target dependencies of the executable 145 | ## same as for the library above 146 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 147 | 148 | ## Specify libraries to link a library or executable target against 149 | # target_link_libraries(${PROJECT_NAME}_node 150 | # ${catkin_LIBRARIES} 151 | # ) 152 | 153 | ############# 154 | ## Install ## 155 | ############# 156 | 157 | # all install targets should use catkin DESTINATION variables 158 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html 159 | 160 | ## Mark executable scripts (Python etc.) for installation 161 | ## in contrast to setup.py, you can choose the destination 162 | # catkin_install_python(PROGRAMS 163 | # scripts/my_python_script 164 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 165 | # ) 166 | 167 | ## Mark executables for installation 168 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html 169 | # install(TARGETS ${PROJECT_NAME}_node 170 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 171 | # ) 172 | 173 | ## Mark libraries for installation 174 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html 175 | # install(TARGETS ${PROJECT_NAME} 176 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 177 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 178 | # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} 179 | # ) 180 | 181 | ## Mark cpp header files for installation 182 | # install(DIRECTORY include/${PROJECT_NAME}/ 183 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 184 | # FILES_MATCHING PATTERN "*.h" 185 | # PATTERN ".svn" EXCLUDE 186 | # ) 187 | 188 | ## Mark other files for installation (e.g. launch and bag files, etc.) 189 | # install(FILES 190 | # # myfile1 191 | # # myfile2 192 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 193 | # ) 194 | 195 | ############# 196 | ## Testing ## 197 | ############# 198 | 199 | ## Add gtest based cpp test target and link libraries 200 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_beginner_tutorials.cpp) 201 | # if(TARGET ${PROJECT_NAME}-test) 202 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) 203 | # endif() 204 | 205 | ## Add folders to be run by python nosetests 206 | # catkin_add_nosetests(test) 207 | 208 | 209 | add_executable(talker src/talker.cpp) 210 | target_link_libraries(talker ${catkin_LIBRARIES}) -------------------------------------------------------------------------------- /launch/apm_config.yaml: -------------------------------------------------------------------------------- 1 | # Common configuration for APM2 autopilot 2 | # 3 | # node: 4 | /mavros/**: 5 | ros__parameters: 6 | startup_px4_usb_quirk: false 7 | system_id: 255 8 | component_id: 240 9 | 10 | # --- system plugins --- 11 | 12 | # sys_status & sys_time connection options 13 | /mavros/**/conn: 14 | ros__parameters: 15 | heartbeat_rate: 1.0 # send heartbeat rate in Hertz 16 | heartbeat_mav_type: "ONBOARD_CONTROLLER" 17 | timeout: 10.0 # heartbeat timeout in seconds 18 | timesync_rate: 10.0 # TIMESYNC rate in Hertz (feature disabled if 0.0) 19 | system_time_rate: 1.0 # send system time to FCU rate in Hertz (disabled if 0.0) 20 | 21 | # sys_status 22 | /mavros/**/sys: 23 | ros__parameters: 24 | min_voltage: [10.0] # diagnostics min voltage, use a vector i.e. [16.2, 16.0] for multiple batteries, up-to 10 are supported 25 | # to achieve the same on a ROS launch file do: [16.2, 16.0] 26 | disable_diag: false # disable all sys_status diagnostics, except heartbeat 27 | 28 | # sys_time 29 | /mavros/**/time: 30 | ros__parameters: 31 | time_ref_source: "fcu" # time_reference source 32 | timesync_mode: MAVLINK 33 | timesync_avg_alpha: 0.6 # timesync averaging factor 34 | 35 | # --- mavros plugins (alphabetical order) --- 36 | 37 | # 3dr_radio 38 | /mavros/**/tdr_radio: 39 | ros__parameters: 40 | low_rssi: 40 # raw rssi lower level for diagnostics 41 | 42 | # actuator_control 43 | # None 44 | 45 | # command 46 | /mavros/**/cmd: 47 | ros__parameters: 48 | use_comp_id_system_control: false # quirk for some old FCUs 49 | 50 | # dummy 51 | # None 52 | 53 | # ftp 54 | # None 55 | 56 | # global_position 57 | /mavros/**/global_position: 58 | ros__parameters: 59 | frame_id: "map" # origin frame 60 | child_frame_id: "base_link" # body-fixed frame 61 | rot_covariance: 99999.0 # covariance for attitude? 62 | gps_uere: 1.0 # User Equivalent Range Error (UERE) of GPS sensor (m) 63 | use_relative_alt: true # use relative altitude for local coordinates 64 | tf.send: false # send TF? 65 | tf.frame_id: "map" # TF frame_id 66 | tf.global_frame_id: "earth" # TF earth frame_id 67 | tf.child_frame_id: "base_link" # TF child_frame_id 68 | 69 | # imu_pub 70 | /mavros/**/imu: 71 | ros__parameters: 72 | frame_id: "base_link" 73 | # need find actual values 74 | linear_acceleration_stdev: 0.0003 75 | angular_velocity_stdev: 0.0003490659 # 0.02 degrees 76 | orientation_stdev: 1.0 77 | magnetic_stdev: 0.0 78 | 79 | # local_position 80 | /mavros/**/local_position: 81 | ros__parameters: 82 | frame_id: "map" 83 | tf.send: false 84 | tf.frame_id: "map" 85 | tf.child_frame_id: "base_link" 86 | tf.send_fcu: false 87 | 88 | # param 89 | # None, used for FCU params 90 | 91 | # rc_io 92 | # None 93 | 94 | # setpoint_accel 95 | /mavros/**/setpoint_accel: 96 | ros__parameters: 97 | send_force: false 98 | 99 | # setpoint_attitude 100 | /mavros/**/setpoint_attitude: 101 | ros__parameters: 102 | reverse_thrust: false # allow reversed thrust 103 | use_quaternion: false # enable PoseStamped topic subscriber 104 | tf.listen: false # enable tf listener (disable topic subscribers) 105 | tf.frame_id: "map" 106 | tf.child_frame_id: "target_attitude" 107 | tf.rate_limit: 50.0 108 | 109 | # setpoint_raw 110 | /mavros/**/setpoint_raw: 111 | ros__parameters: 112 | thrust_scaling: 1.0 # specify thrust scaling (normalized, 0 to 1) for thrust (like PX4) 113 | 114 | # setpoint_position 115 | /mavros/**/setpoint_position: 116 | ros__parameters: 117 | tf.listen: false # enable tf listener (disable topic subscribers) 118 | tf.frame_id: "map" 119 | tf.child_frame_id: "target_position" 120 | tf.rate_limit: 50.0 121 | mav_frame: LOCAL_NED 122 | 123 | # guided_target 124 | /mavros/**/guided_target: 125 | ros__parameters: 126 | tf.listen: false # enable tf listener (disable topic subscribers) 127 | tf.frame_id: "map" 128 | tf.child_frame_id: "target_position" 129 | tf.rate_limit: 50.0 130 | 131 | # setpoint_velocity 132 | /mavros/**/setpoint_velocity: 133 | ros__parameters: 134 | mav_frame: LOCAL_NED 135 | 136 | # vfr_hud 137 | # None 138 | 139 | # waypoint 140 | /mavros/**/mission: 141 | ros__parameters: 142 | pull_after_gcs: true # update mission if gcs updates 143 | use_mission_item_int: true # use the MISSION_ITEM_INT message instead of MISSION_ITEM 144 | # for uploading waypoints to FCU 145 | 146 | # --- mavros extras plugins (same order) --- 147 | 148 | # adsb 149 | # None 150 | 151 | # debug_value 152 | # None 153 | 154 | # distance_sensor 155 | ## Currently available orientations: 156 | # Check http://wiki.ros.org/mavros/**/Enumerations 157 | ## 158 | /mavros/**/distance_sensor: 159 | ros__parameters: 160 | config: | 161 | rangefinder_pub: 162 | id: 0 163 | frame_id: "lidar" 164 | #orientation: PITCH_270 # sended by FCU 165 | field_of_view: 0.0 # XXX TODO 166 | send_tf: false 167 | sensor_position: {x: 0.0, y: 0.0, z: -0.1} 168 | rangefinder_sub: 169 | subscriber: true 170 | id: 1 171 | orientation: PITCH_270 # only that orientation are supported by APM 3.4+ 172 | 173 | # image_pub 174 | /mavros/**/image: 175 | ros__parameters: 176 | frame_id: "px4flow" 177 | 178 | # fake_gps 179 | /mavros/**/fake_gps: 180 | ros__parameters: 181 | # select data source 182 | use_mocap: true # ~mocap/pose 183 | mocap_transform: false # ~mocap/tf instead of pose 184 | mocap_withcovariance: false # ~mocap/pose uses PoseWithCovarianceStamped Message 185 | use_vision: false # ~vision (pose) 186 | use_hil_gps: true 187 | gps_id: 4 188 | # origin (default: Zürich) 189 | geo_origin.lat: 47.3667 # latitude [degrees] 190 | geo_origin.lon: 8.5500 # longitude [degrees] 191 | geo_origin.alt: 408.0 # altitude (height over the WGS-84 ellipsoid) [meters] 192 | eph: 2.0 193 | epv: 2.0 194 | horiz_accuracy: 0.5 195 | vert_accuracy: 0.5 196 | speed_accuracy: 0.0 197 | satellites_visible: 6 # virtual number of visible satellites 198 | fix_type: 3 # type of GPS fix (default: 3D) 199 | tf.listen: false 200 | tf.send: false # send TF? 201 | tf.frame_id: "map" # TF frame_id 202 | tf.child_frame_id: "fix" # TF child_frame_id 203 | tf.rate_limit: 10.0 # TF rate 204 | gps_rate: 5.0 # GPS data publishing rate 205 | 206 | # landing_target 207 | /mavros/**/landing_target: 208 | ros__parameters: 209 | listen_lt: false 210 | mav_frame: "LOCAL_NED" 211 | land_target_type: "VISION_FIDUCIAL" 212 | image.width: 640 # [pixels] 213 | image.height: 480 214 | camera.fov_x: 2.0071286398 # default: 115 [degrees] 215 | camera.fov_y: 2.0071286398 216 | tf.send: true 217 | tf.listen: false 218 | tf.frame_id: "landing_target" 219 | tf.child_frame_id: "camera_center" 220 | tf.rate_limit: 10.0 221 | target_size: {x: 0.3, y: 0.3} 222 | 223 | # mocap_pose_estimate 224 | /mavros/**/mocap: 225 | ros__parameters: 226 | # select mocap source 227 | use_tf: false # ~mocap/tf 228 | use_pose: true # ~mocap/pose 229 | 230 | # mount_control 231 | /mavros/**/mount: 232 | ros__parameters: 233 | debounce_s: 4.0 234 | err_threshold_deg: 10.0 235 | negate_measured_roll: false 236 | negate_measured_pitch: false 237 | negate_measured_yaw: false 238 | 239 | # odom 240 | /mavros/**/odometry: 241 | ros__parameters: 242 | fcu.odom_parent_id_des: "map" # desired parent frame rotation of the FCU's odometry 243 | fcu.odom_child_id_des: "map" # desired child frame rotation of the FCU's odometry 244 | 245 | # px4flow 246 | /mavros/**/px4flow: 247 | ros__parameters: 248 | frame_id: "px4flow" 249 | ranger_fov: 0.118682 # 6.8 degrees at 5 meters, 31 degrees at 1 meter 250 | ranger_min_range: 0.3 # meters 251 | ranger_max_range: 5.0 # meters 252 | 253 | # vision_pose_estimate 254 | /mavros/**/vision_pose: 255 | ros__parameters: 256 | tf.listen: false # enable tf listener (disable topic subscribers) 257 | tf.frame_id: "map" 258 | tf.child_frame_id: "vision_estimate" 259 | tf.rate_limit: 10.0 260 | 261 | # vision_speed_estimate 262 | /mavros/**/vision_speed: 263 | ros__parameters: 264 | listen_twist: true # enable listen to twist topic, else listen to vec3d topic 265 | twist_cov: true # enable listen to twist with covariance topic 266 | 267 | # vibration 268 | /mavros/**/vibration: 269 | ros__parameters: 270 | frame_id: "base_link" 271 | 272 | # wheel_odometry 273 | /mavros/**/wheel_odometry: 274 | ros__parameters: 275 | count: 2 # number of wheels to compute odometry 276 | use_rpm: false # use wheel's RPM instead of cumulative distance to compute odometry 277 | wheel0: {x: 0.0, y: -0.15, radius: 0.05} # x-, y-offset (m,NED) and radius (m) 278 | wheel1: {x: 0.0, y: 0.15, radius: 0.05} # x-, y-offset (m,NED) and radius (m) 279 | send_raw: true # send wheel's RPM and cumulative distance (~/wheel_odometry/rpm, ~/wheel_odometry/distance) 280 | send_twist: false # send geometry_msgs/TwistWithCovarianceStamped instead of nav_msgs/Odometry 281 | frame_id: "map" # origin frame 282 | child_frame_id: "base_link" # body-fixed frame 283 | vel_error: 0.1 # wheel velocity measurement error 1-std (m/s) 284 | tf.send: true 285 | tf.frame_id: "map" 286 | tf.child_frame_id: "base_link" 287 | 288 | # vim:set ts=2 sw=2 et: 289 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | // Build tasks 7 | { 8 | "label": "build", 9 | "detail": "Build workspace (default)", 10 | "type": "shell", 11 | "command": "colcon build --allow-overriding cpp_pubsub --cmake-args '-DCMAKE_BUILD_TYPE=RelWithDebInfo' '-DCMAKE_EXPORT_COMPILE_COMMANDS=On' -Wall -Wextra -Wpedantic", // --merge-install --symlink-install --cmake-args '-DCMAKE_BUILD_TYPE=RelWithDebInfo' '-DCMAKE_EXPORT_COMPILE_COMMANDS=On' -Wall -Wextra -Wpedantic", 12 | // "command": "bash ./build.sh", 13 | "options": {"cwd":"${workspaceFolder}/ros2_ws/"}, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | }, 18 | "problemMatcher": "$gcc" 19 | }, 20 | { 21 | "label": "debug", 22 | "detail": "Build workspace (debug)", 23 | "type": "shell", 24 | "command": "colcon build --merge-install --symlink-install --cmake-args '-DCMAKE_BUILD_TYPE=Debug' -Wall -Wextra -Wpedantic", 25 | // "command": "bash ./build.sh", 26 | "options": {"cwd":"${workspaceFolder}/ros2_ws/"}, 27 | "group": "build", 28 | "problemMatcher": "$gcc" 29 | }, 30 | // Test tasks 31 | { 32 | "label": "test", 33 | "detail": "Run all unit tests and show results.", 34 | "type": "shell", 35 | "command": "colcon test --merge-install --symlink-install; colcon test-result", 36 | "group": { 37 | "kind": "test", 38 | "isDefault": true 39 | } 40 | }, 41 | // Clean 42 | { 43 | "label": "clean", 44 | "detail": "Run the clean target", 45 | "type": "shell", 46 | "command": "colcon build --cmake-target clean", 47 | "problemMatcher": "$gcc" 48 | }, 49 | { 50 | "label": "purge", 51 | "detail": "Purge workspace by deleting all generated files.", 52 | "type": "shell", 53 | "command": "rm -fr build install log; py3clean .", 54 | "problemMatcher": [] 55 | }, 56 | // Linting and static code analysis tasks 57 | { 58 | "label": "fix", 59 | "detail": "Reformat files with uncrustify.", 60 | "type": "shell", 61 | "command": "ament_uncrustify --reformat src/", 62 | "problemMatcher": [] 63 | }, 64 | { 65 | "label": "uncrustify", 66 | "detail": "Lint files with uncrustify.", 67 | "type": "shell", 68 | "command": "ament_uncrustify src/", 69 | "presentation": { 70 | "panel": "dedicated", 71 | "reveal": "silent", 72 | "clear": true 73 | }, 74 | "problemMatcher": [ 75 | { 76 | "owner": "uncrustify", 77 | "source": " uncrustify", 78 | "fileLocation": "relative", 79 | "pattern": [ 80 | /// just the file name message 81 | { 82 | "regexp": "^(.*)'(.*)':", 83 | "kind": "file", 84 | "file": 2, 85 | "message": 1 86 | }, 87 | ] 88 | } 89 | ] 90 | }, 91 | { 92 | "label": "cpplint", 93 | "detail": "Lint files with cpplint.", 94 | "type": "shell", 95 | "command": "ament_cpplint src/", 96 | "presentation": { 97 | "panel": "dedicated", 98 | "reveal": "silent", 99 | "clear": true 100 | }, 101 | "problemMatcher": [ 102 | { 103 | "owner": "cpplint", 104 | "source": " cpplint", 105 | "fileLocation": "absolute", 106 | "pattern": [ 107 | { 108 | "regexp": "^(.+):(\\d+):\\s+(.+)\\[(.+)\\]$", 109 | "file": 1, 110 | "line": 2, 111 | "message": 3, 112 | "code": 4 113 | } 114 | ] 115 | } 116 | ] 117 | }, 118 | { 119 | "label": "cppcheck", 120 | "detail": "Run static code checker cppcheck.", 121 | "type": "shell", 122 | "command": "ament_cppcheck src/", 123 | "presentation": { 124 | "panel": "dedicated", 125 | "reveal": "silent", 126 | "clear": true 127 | }, 128 | "problemMatcher": [ 129 | { 130 | "owner": "cppcheck", 131 | "source": "cppcheck", 132 | "pattern": [ 133 | { 134 | "regexp": "^\\[(.+):(\\d+)\\]:\\s+(.+)$", 135 | "file": 1, 136 | "line": 2, 137 | "message": 3 138 | } 139 | ] 140 | } 141 | ] 142 | }, 143 | { 144 | "label": "lint_cmake", 145 | "detail": "Run lint on cmake files.", 146 | "type": "shell", 147 | "command": "ament_lint_cmake src/", 148 | "presentation": { 149 | "panel": "dedicated", 150 | "reveal": "silent", 151 | "clear": true 152 | }, 153 | "problemMatcher": [ 154 | { 155 | "owner": "lint_cmake", 156 | "source": "lint_cmake", 157 | "pattern": [ 158 | { 159 | "regexp": "^(.+):(\\d+):\\s+(.+)$", 160 | "file": 1, 161 | "line": 2, 162 | "message": 3 163 | } 164 | ] 165 | } 166 | ] 167 | }, 168 | { 169 | "label": "flake8", 170 | "detail": "Run flake8 on python files.", 171 | "type": "shell", 172 | "command": "ament_flake8 src/", 173 | "presentation": { 174 | "panel": "dedicated", 175 | "reveal": "silent", 176 | "clear": true 177 | }, 178 | "problemMatcher": [ 179 | { 180 | "owner": "flake8", 181 | "source": "flake8", 182 | "pattern": [ 183 | { 184 | "code": 4, 185 | "column": 3, 186 | "file": 1, 187 | "line": 2, 188 | "message": 5, 189 | "regexp": "^(.+):(\\d+):(\\d+): (\\w\\d+) (.+)$" 190 | } 191 | ] 192 | } 193 | ] 194 | }, 195 | { 196 | "label": "pep257", 197 | "detail": "Run pep257 on python files.", 198 | "type": "shell", 199 | "command": "ament_pep257 src/", 200 | "presentation": { 201 | "panel": "dedicated", 202 | "reveal": "silent", 203 | "clear": true 204 | }, 205 | "problemMatcher": [ 206 | { 207 | "owner": "pep257", 208 | "source": "pep257", 209 | "pattern": [ 210 | { 211 | "regexp": "^(.+):(\\d+)\\s+(.+):\\s+(.+):\\s+(.+)$", 212 | "file": 1, 213 | "line": 2, 214 | "code": 4, 215 | "message": 5 216 | } 217 | ] 218 | } 219 | ] 220 | }, 221 | { 222 | "label": "xmllint", 223 | "detail": "Run xmllint on xml files.", 224 | "type": "shell", 225 | "command": "ament_xmllint src/", 226 | "presentation": { 227 | "panel": "dedicated", 228 | "reveal": "silent", 229 | "clear": true 230 | }, 231 | "problemMatcher": [ 232 | { 233 | "owner": "xmllint", 234 | "source": "xmllint", 235 | "fileLocation": "absolute", 236 | "pattern": [ 237 | { 238 | "regexp": "^(.+):(\\d+):\\s+(.+)\\s+:\\s+(.+)$", 239 | "file": 1, 240 | "line": 2, 241 | "code": 3, 242 | "message": 4 243 | } 244 | ] 245 | } 246 | ] 247 | }, 248 | { 249 | "label": "lint all", 250 | "detail": "Run all linters.", 251 | "dependsOn":["cppcheck", "cpplint", "flake8", "lint_cmake", "pep257","xmllint", "uncrustify"], 252 | "problemMatcher": [] 253 | }, 254 | // Workspace editing tasks 255 | { 256 | "label": "new ament_cmake package", 257 | "detail": "Create a new ROS cpp package from a template.", 258 | "type": "shell", 259 | "command": "ros2 pkg create --destination-directory src --build-type ament_cmake ${input:package}", 260 | "problemMatcher": [] 261 | }, 262 | { 263 | "label": "new ament_python package", 264 | "detail": "Create a new ROS python package from a template.", 265 | "type": "shell", 266 | "command": "ros2 pkg create --destination-directory src --build-type ament_python ${input:package}", 267 | "problemMatcher": [] 268 | }, 269 | { 270 | "label": "import from workspace file", 271 | "detail": "Use vcs to import modules specified by a workspace/rosinstall file.", 272 | "type": "shell", 273 | "command": "vcs import < src/ros2.repos src", 274 | "problemMatcher": [] 275 | }, 276 | { 277 | "label": "update workspace file", 278 | "detail": "Use vcs to update repositories in src to workspace file.", 279 | "type": "shell", 280 | "command": "vcs export src > src/ros2.repos", 281 | "problemMatcher": [] 282 | }, 283 | { 284 | "label": "install dependencies", 285 | "detail": "Install all dependencies specified in the workspaces package.xml files.", 286 | "type": "shell", 287 | "command": "sudo apt-get update && rosdep update && rosdep install --from-paths src --ignore-src -y", 288 | "problemMatcher": [] 289 | } 290 | ], 291 | "inputs": [ 292 | { 293 | "id": "package", 294 | "type": "promptString", 295 | "description": "Package name" 296 | } 297 | ] 298 | } 299 | -------------------------------------------------------------------------------- /dockerfiles/ros1-2-ignition/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Docker Images](https://github.com/remaro-network/tudelft_hackathon/actions/workflows/container.yaml/badge.svg)](https://github.com/remaro-network/tudelft_hackathon/actions/workflows/container.yaml) 2 | 3 | # REMARO Summer School Delft 2022 - Underwater robotics hackathon 4 | 5 | The overall goal of this hackathon is to provide hands-on training for the Early Stage Researchers (ESRs) 6 | of the REMARO network (but not limited to) on how to architect, program, simulate and implement basic 7 | underwater robot functionalities. 8 | 9 | More specifically, the goals for ESRs with background in: 10 | * **Mathematics/Computer Science:** Learn basic robotics workflow and commonly used tools 11 | * **Robotics:** learn cutting-edge tools, and details on how to develop robot-specific system 12 | 13 | Thus, this training will address how to setup an underwater robot, such as the [BlueROV2](https://bluerobotics.com/store/rov/bluerov2/), 14 | to run with ROS2, and how to simulate it with Gazebo (Ignition). The idea is that participants 15 | work with a simulation first and then test what is developed in a real BlueROV2, with this they 16 | can begin to understand the challenges and differences of deploying a robot in simulation and in the real world. 17 | 18 | The use case selected for this training is “wall avoidance”. Basically, the goal is for the robot 19 | to navigate an environment and not crash into walls using only sonar data. An initial code for a random 20 | avoidance mission is provided, and the idea is that participants work to develop better missions during this training and improve the system in general. 21 | 22 | More details on instructions for participants can be found in the [PARTICIPANTS_TODO](https://github.com/remaro-network/tudelft_hackathon/blob/ros2/PARTICIPANTS_TODO.md) 23 | 24 | You can check the random wall avoidance behavior on the video: 25 | 26 | [![Youtube video](https://user-images.githubusercontent.com/20564040/175087210-6706607d-c2db-4b25-888e-1973e3d093fb.png)](https://www.youtube.com/watch?v=Zv-int_BIJw) 27 | 28 | ## Acknowledgements 29 | 30 | 31 | REMARO Logo 32 | 33 | 34 | This work is part of the Reliable AI for Marine Robotics (REMARO) Project. For more info, please visit: https://remaro.eu/ 35 | 36 |
37 | 38 |
39 | EU Flag 40 | 41 | 42 | This project has received funding from the European Union's Horizon 2020 research and innovation programme under the Marie Skłodowska-Curie grant agreement No. 956200. 43 | 44 | ## Summary 45 | - [Computer setup](https://github.com/remaro-network/tudelft_hackathon#setup) 46 | - [Bluerov setup](https://github.com/remaro-network/tudelft_hackathon#bluerov-setup) 47 | * [Installation](https://github.com/remaro-network/tudelft_hackathon#installation) 48 | - [Install prerequisites to run with docker](https://github.com/remaro-network/tudelft_hackathon#install-prerequisites-to-run-with-docker) 49 | - [Install locally](https://github.com/remaro-network/tudelft_hackathon#install-locally) 50 | - [Run it with docker via CLI](https://github.com/remaro-network/tudelft_hackathon#run-it-with-docker-via-cli) 51 | - [Run with docker with VSCode ](https://github.com/remaro-network/tudelft_hackathon#run-it-with-docker-with-vscode) 52 | - [Run locally](https://github.com/remaro-network/tudelft_hackathon#run-it-locally) 53 | - [Explanation](https://github.com/remaro-network/tudelft_hackathon#explanation) 54 | - [Exercises](https://github.com/remaro-network/tudelft_hackathon#exercises) 55 | - [Additional information](https://github.com/remaro-network/tudelft_hackathon#additional-info) 56 | 57 | ## Setup 58 | 59 | Tested with: 60 | - Ubuntu 22.04 61 | - [ROS2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html) 62 | - [Gazebo (Ignition) Garden](https://gazebosim.org/docs/garden/install_ubuntu) 63 | - [ArduPilot (Sub-4.1)](https://github.com/ArduPilot/ardupilot/tree/f2af3c7ed2907be914c41d8512654a77498d3870) 64 | - [ardupilot_gazebo plugin](https://github.com/ArduPilot/ardupilot_gazebo/tree/ignition-garden) 65 | - [mavros2](https://github.com/mavlink/mavros) 66 | - [remaro_world](https://github.com/remaro-network/remaro_worlds/tree/ign-garden) 67 | - [bluerov2_ignition](https://github.com/Rezenders/bluerov2_ignition) 68 | 69 | ## Bluerov Setup 70 | 71 | - BlueOS (v1.0.1) 72 | 73 | ## Installation 74 | 75 | There are 3 options to use this repo. 76 | Install everything locally in your computer. This will require some effort, but when done should be easier to use. 77 | Run everything with docker (read disclaimer bellow): 78 | - Via the CLI. This option should be faster to reproduce everything, but is a little bit annoying for development. 79 | - Using VSCode. Requires installing VSCode. Should be easier way to use everything. (work in progress) 80 | 81 | **Disclaimer** 82 | Running docker images with graphical user interface is a little bit trick and might not work in all systems. 83 | We tested in a system with ubuntu 22.04 and with a NVIDIA gpu. 84 | It might not work on systems with AMD gpus, and on MAC. 85 | We are going to try to fix this problem until the hackathon, but it is not guaranteed. 86 | In those cases go for the [local installation](https://github.com/remaro-network/tudelft_hackathon#install-locally). 87 | 88 | ### Install prerequisites to run with docker 89 | 90 | - Install docker on your machine. You can find instructions [here](https://docs.docker.com/engine/install/ubuntu/) 91 | - Allow non-root users to manage docker. Instructions [here](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) 92 | - Install VSCode. Instructions [here](https://code.visualstudio.com/download) 93 | - Install [nvidia-docker](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker)(only needed if you have a nvidia GPU) 94 | 95 | ### Configure computer to connect with the BlueROV2 96 | Follow [Bluerobotics instructions](https://bluerobotics.com/learn/bluerov2-software-setup/#software-introduction) 97 | 98 | ### Install locally 99 | #### Install Gazebo Garden 100 | 101 | Follow the [official instructions](https://gazebosim.org/docs/garden/install_ubuntu) for installing Gazebo Garden. 102 | 103 | #### Install ROS2 Humble 104 | 105 | Follow the [official instructions](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html) for installing ROS2 Humble. 106 | 107 | #### Install ardusub 108 | 109 | Instructions can be found [here](https://ardupilot.org/dev/docs/building-setup-linux.html#building-setup-linux) 110 | 111 | **Disclaimer:** 112 | Problems may occur with different combinations of ArduPilot and MavROS versions. 113 | 114 | ```Bash 115 | cd ~/ 116 | git clone https://github.com/ArduPilot/ardupilot.git 117 | cd ardupilot 118 | git checkout e9f46b9 119 | git submodule update --init --recursive 120 | ``` 121 | 122 | Note that the script used to install prerequisites available for this 123 | version of ArduSub does not work in Ubuntu 22.04. Therefore, you need to replace them before 124 | running ArduSub. To install the ArduPilot prerequisites, do the following. 125 | 126 | ```Bash 127 | cd ~/ardupilot 128 | cd Tools/environment_install/ 129 | rm install-prereqs-ubuntu.sh 130 | wget https://raw.githubusercontent.com/ArduPilot/ardupilot/master/Tools/environment_install/install-prereqs-ubuntu.sh 131 | cd ~/ardupilot 132 | chmod +x Tools/environment_install/install-prereqs-ubuntu.sh 133 | Tools/environment_install/install-prereqs-ubuntu.sh -y 134 | . ~/.profile 135 | ``` 136 | 137 | If you want to use MAC, follow [this instruction](https://ardupilot.org/dev/docs/building-setup-mac.html) 138 | 139 | To test if the installation worked, run: 140 | 141 | ```Bash 142 | sim_vehicle.py -v ArduSub -L RATBeach --console --map 143 | ``` 144 | 145 | Ardupilot SITL should open and a console plus a map should appear. 146 | 147 | **Troubleshoot** 148 | If you have problems with the install-prereqs-ubuntu.sh script try to install the dependencies manually with the following commands. 149 | 150 | ```Bash 151 | pip3 install --user -U future lxml pymavlink MAVProxy pexpect flake8 geocoder empy dronecan pygame intelhex 152 | ``` 153 | 154 | ```Bash 155 | sudo apt-get --assume-yes install build-essential ccache g++ gawk git make wget python-is-python3 libtool libxml2-dev libxslt1-dev python3-dev python3-pip python3-setuptools python3-numpy python3-pyparsing python3-psutil xterm python3-matplotlib python3-serial python3-scipy python3-opencv libcsfml-dev libcsfml-audio2.5 libcsfml-dev libcsfml-graphics2.5 libcsfml-network2.5 libcsfml-system2.5 libcsfml-window2.5 libsfml-audio2.5 libsfml-dev libsfml-graphics2.5 libsfml-network2.5 libsfml-system2.5 libsfml-window2.5 python3-yaml libpython3-stdlib python3-wxgtk4.0 fonts-freefont-ttf libfreetype6-dev libpng16-16 libportmidi-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev libtool-bin g++-arm-linux-gnueabihf lcov gcovr 156 | ``` 157 | 158 | #### Install ardusub_plugin 159 | 160 | Install dependencies: 161 | 162 | ```Bash 163 | sudo apt install rapidjson-dev libgz-sim7-dev 164 | ``` 165 | 166 | Clone and build repo: 167 | 168 | ```Bash 169 | cd ~/ 170 | git clone https://github.com/ArduPilot/ardupilot_gazebo 171 | cd ardupilot_gazebo 172 | mkdir build && cd build 173 | cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo 174 | make -j4 175 | ``` 176 | 177 | Add required paths: 178 | 179 | Assuming that you have clone the repository in `$HOME/ardupilot_gazebo`: 180 | ```bash 181 | echo 'export GZ_SIM_SYSTEM_PLUGIN_PATH=$HOME/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH}' >> ~/.bashrc 182 | echo 'export GZ_SIM_RESOURCE_PATH=$HOME/ardupilot_gazebo/models:$HOME/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH}' >> ~/.bashrc 183 | ``` 184 | 185 | Reload your terminal with source ~/.bashrc 186 | 187 | More info about the plugin can be found in the [repo](https://github.com/ArduPilot/ardupilot_gazebo/tree/ignition-garden) 188 | 189 | #### Install hackathon workspace 190 | 191 | Create new workspace: 192 | ```Bash 193 | mkdir -p ~/tudelft_hackathon_ws/src 194 | cd ~/tudelft_hackathon_ws 195 | ``` 196 | 197 | Clone repos: 198 | ```Bash 199 | wget https://raw.githubusercontent.com/remaro-network/tudelft_hackathon/ros2/hackathon.rosinstall 200 | vcs import src < hackathon.rosinstall --recursive 201 | ``` 202 | 203 | Add required paths: 204 | ```Bash 205 | echo 'export GZ_SIM_RESOURCE_PATH=$HOME/tudelft_hackathon_ws/src/bluerov2_ignition/models:$HOME/tudelft_hackathon_ws/src/bluerov2_ignition/worlds:${GZ_SIM_RESOURCE_PATH}' >> ~/.bashrc 206 | 207 | echo 'export GZ_SIM_RESOURCE_PATH=$HOME/tudelft_hackathon_ws/src/remaro_worlds/models:$HOME/tudelft_hackathon_ws/src/remaro_worlds/worlds:${GZ_SIM_RESOURCE_PATH}' >> ~/.bashrc 208 | ``` 209 | 210 | Before building the `ros_gz` package (one of the dependencies), you need to export the gazebo version: 211 | 212 | ``` 213 | export GZ_VERSION="garden" 214 | ``` 215 | You can also add this to your `~/.bashrc` to make this process easier. 216 | 217 | Install deps: 218 | ```Bash 219 | source /opt/ros/humble/setup.bash 220 | cd ~/tudelft_hackathon_ws/ 221 | rosdep install --from-paths src --ignore-src -r -y 222 | ``` 223 | 224 | Build project: 225 | ```Bash 226 | cd ~/tudelft_hackathon_ws/ 227 | colcon build --symlink-install 228 | ``` 229 | 230 | ## Run it with docker via CLI 231 | 232 | Create docker network: 233 | 234 | ```Bash 235 | sudo docker network create ros_net 236 | ``` 237 | 238 | ### Run Ignition simulation + ardupilot SITL: 239 | 240 | If you a NVIDIA GPU: 241 | ```Bash 242 | xhost +local:root 243 | sudo docker run -it --rm --name ignition --net ros_net -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --gpus all ghcr.io/remaro-network/tudelft_hackathon:nvidia ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py ardusub:=true mavros_url:='bluerov:14551' 244 | ``` 245 | 246 | If you have an AMD GPU: 247 | ```Bash 248 | xhost +local:root ; 249 | sudo docker run -it --rm --name ignition --net ros_net -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --device=/dev/dri --group-add video ghcr.io/remaro-network/tudelft_hackathon:non-nvidia ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py ardusub:=true mavros_url:='bluerov:14551' 250 | ``` 251 | 252 | If you have an Intel GPU: 253 | ```Bash 254 | xhost +local:root ; 255 | sudo docker run -it --rm --name ignition --net ros_net -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro --device=/dev/dri:/dev/dri ghcr.io/remaro-network/tudelft_hackathon:non-nvidia ros2 launch tudelft_hackathon bluerov_ign_sim.launch.py ardusub:=true mavros_url:='bluerov:14551' 256 | ``` 257 | 258 | ### Run bluerov software: 259 | 260 | ```Bash 261 | sudo docker run -it --rm --name bluerov --net ros_net ghcr.io/remaro-network/tudelft_hackathon_base:latest ros2 launch tudelft_hackathon bluerov_bringup_no_ign.launch.py fcu_url:=udp://:14551@ignition:14555 262 | ``` 263 | 264 | ### Development with docker via cli 265 | 266 | To add your modifications into the docker images you need to rebuild the relevant docker images. 267 | In this case, run the `build-dev-images.sh` script to rebuild them. And make sure to substitute in the `docker run` commands the images from rezenders to you local images. I.e: `rezenders/ignition:hackathon` -> `ignition:hackathon-dev` and `rezenders/ros-foxy-hackathon` -> `ros-foxy-hackathon:dev` 268 | 269 | ## Run it with docker with VSCode 270 | 271 | Check instructions [here](https://github.com/remaro-network/tudelft_hackathon/blob/ros2/dockerfiles/ros1-2-ignition/README.md) 272 | 273 | ## Run it locally 274 | 275 | ### Simulation 276 | Before running anything you need to source the workspace. With this command: 277 | 278 | ```Bash 279 | source ~/tudelft_hackathon_ws/install/setup.bash 280 | ``` 281 | 282 | Or you can add that to the ~/.bashrc file to prevent needing to source everytime. 283 | 284 | ```Bash 285 | echo "source ~/tudelft_hackathon_ws/install/setup.bash" >> ~/.bashrc 286 | ``` 287 | Don't forget to re-open your terminal after altering the `~/.bashrc` file. 288 | 289 | In one terminal run ardusub SITL: 290 | ```Bash 291 | sim_vehicle.py -L RATBeach -v ArduSub --model=JSON --console 292 | ``` 293 | 294 | In another terminal run the simulation + mavros + agent: 295 | ```Bash 296 | ros2 launch tudelft_hackathon bluerov_bringup.launch.py simulation:=true ardusub:=false 297 | ``` 298 | 299 | ### Bluerov2 300 | 301 | ```Bash 302 | ros2 launch tudelft_hackathon bluerov_bringup.launch.py simulation:=false 303 | ``` 304 | 305 | ## Explanation 306 | 307 | Simplified system architecture: 308 | 309 | ![System architecture](https://user-images.githubusercontent.com/20564040/174649275-41a2d0bd-54ed-485f-bfcb-36ffe94dd11c.png) 310 | 311 | The system was designed to be used both with a real or simulated BlueROV2. When 312 | used with a simulation, the left nodes are deployed. And when used with the real 313 | robot the right nodes are deployed.The agent and MAVROS nodes are always deployed. 314 | 315 | First, let's take a look on how the real BlueROV2 works, then we see how the simulation 316 | is setup to mimic it. 317 | 318 | ### Real BlueROV2 319 | 320 | **BlueROV2:** The BlueROV2 that is going to be used for the hackathon has the [heavy configuration](https://bluerobotics.com/store/rov/bluerov2-upgrade-kits/brov2-heavy-retrofit/). It is equipped with the [Ping 360](https://bluerobotics.com/store/sensors-sonars-cameras/sonar/ping360-sonar-r1-rp/) mechanical scanning sonar mounted in the [standard location](https://bluerobotics.com/learn/ping360-installation-guide-for-the-bluerov2/#mounting-the-ping360-to-the-embluerov2em-frame-heavy). And ArduSub runs on a [Pixhawk](https://bluerobotics.com/store/comm-control-power/control/pixhawk-r1-rp/). 321 | 322 | **Ping360 sonar driver:** To get data from the sonar the [ping360_sonar](https://github.com/CentraleNantesRobotics/ping360_sonar) ROS2 package is being used. It provides data in the following topics: 323 | 324 | | Topic | Message type | Description | 325 | | ------------- | ------------- | ------------- | 326 | | /scan_image | [sensor_msgs/Image](https://github.com/ros2/common_interfaces/blob/master/sensor_msgs/msg/Image.msg) | The generated sonar image in gray level| 327 | | /echo | [ping360_sonar_msg/SonarEcho](https://github.com/CentraleNantesRobotics/ping360_sonar/blob/ros2/ping360_sonar_msgs/msg/SonarEcho.msg) | Raw sonar data| 328 | | /scan | [sensor_msgs/LaserScan](https://github.com/ros2/common_interfaces/blob/master/sensor_msgs/msg/LaserScan.msg) | Publishes a LaserScan msg with ranges detected above a certain intensity threshold (0-255). The intensities of the message are scaled down to (0,1)| 329 | 330 | Using this package, the Ping360 sonar takes between 6 and 10 seconds to complete a 360 degree rotation. 331 | 332 | **ArduSub:** According to their [website](https://www.ardusub.com/) ArduSub is "is a fully-featured open-source solution for remotely operated underwater vehicles (ROVs) and autonomous underwater vehicles (AUVs). ArduSub is a part of the [ArduPilot](https://ardupilot.org/) project, and was originally derived from the ArduCopter code. ArduSub has extensive capabilities out of the box including feedback stability control, depth and heading hold, and autonomous navigation". 333 | 334 | With the current configuration, BlueROV2 is not able to calculate its 3D position as there are no sensors that provide enough information for this, such as DVL, underwater GPS, etc. 335 | Thus, it is only possible to operate the robot using [flight modes](https://ardupilot.org/copter/docs/flight-modes.html#gps-dependency) that don't require positioning data, such as MANUAL, STABILIZE, and DEPTH HOLD. See [ArduSub flight modes](https://www.ardusub.com/reference/ardusub/features-while-in-operation.html#flight-modes). 336 | Consequently, it is not possible to send waypoints or velocity commands to the robot, the only way to operate it is by overriding the [RC inputs](https://www.ardusub.com/developers/rc-input-and-output.html#rc-inputs). 337 | 338 | **MAVROS:** The [MAVROS](https://github.com/mavlink/mavros) package is used to bridge the communication between ROS and mavlink, which is the communication protocol used by ArduSub. Which means MAVROS can be used as a bridge between ROS and ArduSub. To connect it to ArduSub it necesary to set the following parameters: 339 | - `fcu_url`: Address of the flight controller unit. For this case: `udp://192.168.2.1:14550@192.168.2.2:14555` 340 | 341 | MAVROS provides an extensive number of topics and services to interact with autopilots, you can check the full list [here](http://wiki.ros.org/mavros). For our use case, the topics and services being used are: 342 | 343 | | Topic | Message type | Description | 344 | | ------------- | ------------- | ------------- | 345 | | mavros/state | [mavros_msgs/State](https://github.com/mavlink/mavros/blob/ros2/mavros_msgs/msg/State.msg) |Provides the FCU state | 346 | | mavros/rc/override | [mavros_msgs/OverrideRCIn](https://github.com/mavlink/mavros/blob/ros2/mavros_msgs/msg/OverrideRCIn.msg) | Send RC override message to FCU | 347 | 348 | | Service | Message type | Description | 349 | | ------------- | ------------- | ------------- | 350 | | mavros/set_mode |[mavros_msgs/SetMode](https://github.com/mavlink/mavros/blob/ros2/mavros_msgs/srv/SetMode.srv)| Set FCU flight mode | 351 | | mavros/cmd/arming |[mavros_msgs/CommandBool](https://github.com/mavlink/mavros/blob/ros2/mavros_msgs/srv/CommandBool.srv)| Change arming status| 352 | 353 | 354 | To simplify interactions with MAVROS, a [wrapper](https://github.com/remaro-network/mavros_wrapper) was setup with the basic functionalities needed for this hackathon. It works like this: 355 | 356 | ```Python 357 | from mavros_wrapper.ardusub_wrapper import * # Import wrapper 358 | 359 | ardusub = BlueROVArduSubWrapper("ardusub_node") # create new instance with desired node name 360 | status = ardusub.status # to get FCU status 361 | ardusub.set_mode("MANUAL") # set FCU flight mode to MANUAL 362 | ardusub.arm_motors(True) # arm motors 363 | ardusub.toogle_rc_override(True) # start overriding RC 364 | ardusub.set_rc_override_channels(forward=0.5) # set values to override 365 | ``` 366 | 367 | **Agent:** The agent node is the one that decides how the robot should behave. 368 | For this hackathon, we setup two different nodes with simple behaviors: 369 | 370 | The [bluerov_agent](https://github.com/remaro-network/tudelft_hackathon/blob/ros2/scripts/bluerov_agent.py) has the following behavior. The robot set its flight mode to `MANUAL`, then arms the thrusters, then go around in a square path once. For this, the agent uses the topics & services listed in the mavros section. 371 | 372 | Let's break the code and understand what's going on below the surface. 373 | 374 | The main function: 375 | ```Python 376 | if __name__ == '__main__': 377 | rclpy.init(args=sys.argv) 378 | 379 | ardusub = BlueROVArduSubWrapper("ardusub_node") 380 | 381 | thread = threading.Thread(target=rclpy.spin, args=(ardusub, ), daemon=True) 382 | thread.start() 383 | 384 | mission(ardusub) 385 | ``` 386 | First the `rclpy` library is initialized. Then the ardusub node is created using the `BlueROVArduSubWrapper` class defined in the `mavros_wrapper` package. Following, a new thread is created to spin the ardusub node in parallel, this is necessary because we are going to use some sleep functions in the main thread later and we want the ardusub node to keep spinning despite of that. Lastly, the `mission` function is called, which is where the mission of the robot is defined. 387 | 388 | Now let's take a look in the `mission` function 389 | ```Python 390 | def mission(ardusub): 391 | 392 | service_timer = ardusub.create_rate(2) 393 | while ardusub.status.mode != "MANUAL": 394 | ardusub.set_mode("MANUAL") 395 | service_timer.sleep() 396 | 397 | print("Manual mode selected") 398 | 399 | while ardusub.status.armed == False: 400 | ardusub.arm_motors(True) 401 | service_timer.sleep() 402 | 403 | print("Thrusters armed") 404 | 405 | print("Initializing mission") 406 | 407 | timer = ardusub.create_rate(0.5) # Hz 408 | 409 | ardusub.toogle_rc_override(True) 410 | ardusub.set_rc_override_channels(forward=0.5) 411 | timer.sleep() 412 | ardusub.set_rc_override_channels(lateral=0.5) 413 | timer.sleep() 414 | ardusub.set_rc_override_channels(forward=-0.5) 415 | timer.sleep() 416 | ardusub.set_rc_override_channels(lateral=-0.5) 417 | timer.sleep() 418 | ardusub.set_rc_override_channels(lateral=0) 419 | ardusub.toogle_rc_override(False) 420 | 421 | print("Mission completed") 422 | ``` 423 | A `service_timer` timer is created with 2Hz rate. Then we have a while loop that keeps trying to change the flight mode to `MANUAL` until the flight mode is set to `MANUAL`, note that the `ardusub.set_mode("MANUAL")` method from the mavros_wrapper explained earlier is used for this, and that the `service_timer` is used to make the loop wait for 0.5 seconds before repeating. Following, we have a similar loop to arm the motors. 424 | 425 | After that, we create a new timer with 0.5Hz rate. The `ardusub.toogle_rc_override(True)` method is called to make the ardusub node start publishing messages in the `/mavros/rc/override` topic. Then, we use the method `ardusub.set_rc_override_channels(forward=0.5)` to make the robot move forward with half of its thrust, this is achieved internally by the ardusub node by publishing the appropriate message in the `/mavros/rc/override` topic. Following, the program sleeps for 2 seconds and then we make the robot move again to other directions, in order to go "around" a square. And that is it. 426 | 427 | 428 | The [random_wall_avoidance](https://github.com/remaro-network/tudelft_hackathon/blob/ros2/scripts/random_wall_avoidance.py) has the following behavior. The robot set its flight mode to `ALT HOLD`, then arms the thrusters, then starts moving forward. The agent subscribes to the sonar topic and every time it receives sonar readings it checks if there is an obstacle in its front, e.g. 180°, closer than a certain threshold, e.g. 1.25m, and in case there is it rotates randomly until there are no more obstacle. For this, the agent uses the topics & services listed in the mavros section, and the `/scan` topic described in the ping360 driver section. 429 | 430 | ### Simulated BlueROV2 431 | 432 | **Simulated BlueROV2:** To simulate the BlueROV2 we are using Gazebo (Ignition). Unfortunately, until the moment of writing this readme, there is no sonar plugin for Ignition. Thus, we are using a lidar plugin instead, configured to have the same speed and measurement range as the Ping360 sonar. The bluerov2 model is [here](https://github.com/Rezenders/bluerov2_ignition/blob/main/models/bluerov2/model.sdf) and the bluerov2 model with a lidar is [here](https://github.com/Rezenders/bluerov2_ignition/blob/main/models/bluerov2_lidar/model.sdf). The world being used for the simulation can be found [here](https://github.com/remaro-network/remaro_worlds/blob/ign-garden/worlds/room_walls.world), note that there is a buoyancy plugin that sets the "water" density to 1000kg/m3. 433 | 434 | **Simulated "sonar" bridge:** In order to have access to the simulated lidar data with ROS2 we run a bridge between ignition transport and ROS2. Something like this: 435 | 436 | Via command line: 437 | ``` 438 | ros2 run ros_gz_bridge parameter_bridge lidar@sensor_msgs/msg/LaserScan@ignition.msgs.LaserScan -r /lidar:=/scan 439 | ``` 440 | 441 | With launch file: 442 | ``` 443 | package='ros_gz_bridge', 444 | executable='parameter_bridge', 445 | arguments=['lidar@sensor_msgs/msg/LaserScan@ignition.msgs.LaserScan'], 446 | remappings=[('/lidar','/scan')], 447 | output='screen' 448 | ``` 449 | 450 | Note that the topic where the lidar data is published has the same name (`/scan`) and type (`sensor_msgs/LaserScan`) as the topic published by the ping360 driver. 451 | 452 | **ArduSub Sofware In The Loop (SITL):** Since when running the simulation we don't have a board with an autopilot installed, we simulate Ardusub as a SITL. 453 | 454 | **Ardupilot gazebo plugin:** Bridge between Ignition and Ardusub. More info can be found [here](https://gazebosim.org/api/gazebo/7.0/ardupilot.html). 455 | 456 | **MAVROS:** The only difference is that for the simulation we need to use a different `fcu_url`. In this case, `udp://:14551@:14555`. 457 | 458 | **Agent:** Since all the interfaces are the same, the agent nodes are the same for both simulation and the real robot. 459 | 460 | ## Exercises 461 | 462 | The main exercise of this training is to implement an avoidance algorithm based on potential fields, you can find more info on the issue [#36](https://github.com/remaro-network/tudelft_hackathon/issues/36). 463 | 464 | Check [PARTICIPANTS_TODO](https://github.com/remaro-network/tudelft_hackathon/blob/ros2/PARTICIPANTS_TODO.md#activities-to-be-done-during-hackathon) for extra info. 465 | 466 | ## Additional info 467 | 468 | ### SSH into bluerov (blueOS) 469 | 470 | Password: raspberry 471 | ```Bash 472 | $ ssh pi@192.168.2.2 473 | ``` 474 | 475 | ## Related repository 476 | 477 | [SUAVE](https://github.com/kas-lab/suave#install-the-exemplar-locally): An Exemplar for Self-Adaptive Underwater Vehicles 478 | --------------------------------------------------------------------------------