diff --git a/.github/workflows/docs-sphinx-build-check.yml b/.github/workflows/docs-sphinx-build-check.yml index 430bd51f..2e17cca0 100644 --- a/.github/workflows/docs-sphinx-build-check.yml +++ b/.github/workflows/docs-sphinx-build-check.yml @@ -5,15 +5,13 @@ on: branches: - rolling schedule: - # Run every morning to detect flakiness and broken dependencies + # Run every day to detect flakiness and broken dependencies - cron: '23 5 * * *' jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: ammaraskar/sphinx-action@master + - uses: ros-controls/control.ros.org-deployment-scripts@master with: - docs-folder: 'docs/' - pre-build-command: "apt-get update -y && apt-get install -y python3-pip && pip3 install sphinx_rtd_theme" + install_extensions: false diff --git a/docs/use-cases/index.rst b/docs/use-cases/index.rst index 312e5fe0..ddc6a3ab 100644 --- a/docs/use-cases/index.rst +++ b/docs/use-cases/index.rst @@ -10,5 +10,6 @@ Check the repository and PRs for other, undocumented use-cases. :maxdepth: 1 :glob: - * + operating_system/* + ros_packages/* ros2_control/* diff --git a/docs/use-cases/create_setup_workspace.rst b/docs/use-cases/operating_system/create_setup_workspace.rst similarity index 76% rename from docs/use-cases/create_setup_workspace.rst rename to docs/use-cases/operating_system/create_setup_workspace.rst index b6efc144..70a538c3 100644 --- a/docs/use-cases/create_setup_workspace.rst +++ b/docs/use-cases/operating_system/create_setup_workspace.rst @@ -5,10 +5,6 @@ Setup a new Workspace This use-case describes how to setup a new ROS workspace using scripts from the ROS Team Workspace (RosTeamWS) framework. - -Script for Creating Workspace -============================== - `setup-ros-workspace` accepts ros distro name workspace suffix and workspace folder as parameters. All three parameters are optional. @@ -18,6 +14,5 @@ All three parameters are optional. setup-ros-workspace ROS_DISTRO WS_SUFFIX WS_FOLDER -The script creates... - - +The script creates in the ``$HOME/`` a new ROS workspace with name ``ros_ws__``. +Default value for ```` is "workspace". diff --git a/docs/use-cases/ros2_control/setup_controller.rst b/docs/use-cases/ros2_control/setup_controller.rst index bbaecbae..d3da85d1 100644 --- a/docs/use-cases/ros2_control/setup_controller.rst +++ b/docs/use-cases/ros2_control/setup_controller.rst @@ -1,7 +1,7 @@ ======================================================= -ros2_control: Setup contorller package +ros2_control: Setup controller package ======================================================= -.. _uc-setup-ros2-contorller: +.. _uc-setup-ros2-controller: This use-case describes how to set up a controller for the ros2_control framework using scripts from ROS Team Workspace (RosTeamWS) framework. diff --git a/docs/use-cases/configure_repository.rst b/docs/use-cases/ros_packages/configure_repository.rst similarity index 100% rename from docs/use-cases/configure_repository.rst rename to docs/use-cases/ros_packages/configure_repository.rst diff --git a/docs/use-cases/create_package.rst b/docs/use-cases/ros_packages/create_package.rst similarity index 100% rename from docs/use-cases/create_package.rst rename to docs/use-cases/ros_packages/create_package.rst diff --git a/docs/use-cases/setup_robot_bringup_package.rst b/docs/use-cases/ros_packages/setup_robot_bringup_package.rst similarity index 100% rename from docs/use-cases/setup_robot_bringup_package.rst rename to docs/use-cases/ros_packages/setup_robot_bringup_package.rst diff --git a/docs/use-cases/setup_robot_description_package.rst b/docs/use-cases/ros_packages/setup_robot_description_package.rst similarity index 100% rename from docs/use-cases/setup_robot_description_package.rst rename to docs/use-cases/ros_packages/setup_robot_description_package.rst diff --git a/scripts/_RosTeamWs_Defines.bash b/scripts/_RosTeamWs_Defines.bash index d4f7eed3..c8aa9902 100755 --- a/scripts/_RosTeamWs_Defines.bash +++ b/scripts/_RosTeamWs_Defines.bash @@ -18,6 +18,15 @@ function RosTeamWS_script_own_dir { echo "$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" } +# TODO(denis): add this into setup.bash +function RosTeamWS_setup_aliases { + +# ROS + alias rosd="cd \$ROS_WS" + alias rosds="cd \$ROS_WS/src" + alias rosdb="cd \$ROS_WS/build" +} + function RosTeamWS_setup_ros1_exports { export ROSCONSOLE_FORMAT='[${severity}] [${walltime}: ${logger}] [${node}@${file}.${function}:${line}]: ${message}' @@ -27,6 +36,10 @@ export ROSCONSOLE_CONFIG_FILE='~/workspace/ros_ws/rosconsole.config' function RosTeamWS_setup_ros1_aliases { +# ROS + alias rosdd="cd \$ROS_WS/devel" + +# Catkin alias cb="catkin build" } @@ -40,16 +53,21 @@ function RosTeamWS_setup_ros2_exports { function RosTeamWS_setup_ros2_aliases { +# ROS + alias rosdi="cd \$ROS_WS/install" + +# COLCON alias cb="colcon_build" alias cbr="colcon_build_release" - alias cbup="colcon build --symlink-install --packages-up-to" + alias cbup="colcon_build_up_to" alias ct="colcon_test" - alias ctup="colcon test --packages-up-to" + alias ctup="colcon_test_up_to" - alias ctr="colcon test-result" + alias ctres="colcon_test_results" alias ca="colcon_all" + alias caup="colcon_all_up_to" } @@ -59,18 +77,43 @@ function colcon_helper_ros2 { print_and_exit "This should never happen. Check your helpers definitions!" fi + cd $ROS_WS + CMD="$1" if [ -z "$2" ]; then $CMD else $CMD --packages-select $2 fi + + cd - +} + +function colcon_helper_ros2_up_to { + if [ -z "$1" ]; then + print_and_exit "This should never happen. Check your helpers definitions!" + fi + + cd $ROS_WS + + CMD="$1" + if [ -z "$2" ]; then + print_and_exit "You should provide package for this command!" + else + $CMD --packages-up-to $2 + fi + + cd - } function colcon_build { colcon_helper_ros2 "colcon build --symlink-install" "$*" } +function colcon_build_up_to { + colcon_helper_ros2_up_to "colcon build --symlink-install" "$*" +} + function colcon_build_release { colcon_helper_ros2 "colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release" "$*" } @@ -79,10 +122,30 @@ function colcon_test { colcon_helper_ros2 "colcon test" "$*" } +function colcon_test_up_to { + colcon_helper_ros2_up_to "colcon test" "$*" +} + +function colcon_test_results { + cd $ROS_WS + if [ -z "$1" ]; then + colcon test-result + else + colcon test-result | grep "$*" + fi + cd - +} + function colcon_all { colcon_build "$*" colcon_test "$*" - ctr + colcon_test_results "$*" +} + +function colcon_all_up_to { + colcon_build_up_to "$*" + colcon_test_up_to "$*" + colcon_test_results "$*" } ## END: Default Framework Definitions @@ -162,12 +225,13 @@ function compile_and_source_package { fi bn=`basename "$PWD"` path=$bn - while [[ "$bn" != "src" ]]; do - cd .. - bn=`basename "$PWD"` - path="$bn/$path" - done - cd .. +# while [[ "$bn" != "src" ]]; do +# cd .. +# bn=`basename "$PWD"` +# path="$bn/$path" +# done +# cd .. + cd $ROS_WS colcon build --symlink-install --packages-up-to $pkg_name source install/setup.bash if [[ "$test" == "yes" ]]; then diff --git a/scripts/_Team_Defines.bash b/scripts/_Team_Defines.bash index 8091111b..c4c16ebd 100644 --- a/scripts/_Team_Defines.bash +++ b/scripts/_Team_Defines.bash @@ -24,8 +24,10 @@ TEAM_LICENSE="Apache License 2.0" TEAM_REPOSITORY_SERVER="https://github.com" -# TODO(denis): implement here support for internal repos -# TEAM_INTERNAL_ASSETS="/opt/RosTeamWS/assets/" +TEAM_PRIVATE_CONFIG_PATH="" + +# Define a path to a repository with your internal assets and configurations +TEAM_INTERNAL_ASSETS="/opt/RosTeamWS/assets/" ## END: definitions @@ -44,6 +46,8 @@ check_ros_distro $DEFAULT_ROS_DISTRO # BEGIN: Define aliases for standard internal functions +alias setup_aliases=RosTeamWS_setup_aliases + alias setup_ros1_exports=RosTeamWS_setup_ros1_exports alias setup_ros1_aliases=RosTeamWS_setup_ros1_aliases @@ -51,8 +55,6 @@ alias setup_ros1_aliases=RosTeamWS_setup_ros1_aliases alias setup_ros2_exports=RosTeamWS_setup_ros2_exports alias setup_ros2_aliases=RosTeamWS_setup_ros2_aliases - - # END: Define aliases for standard functions diff --git a/scripts/environment/setup.bash b/scripts/environment/setup.bash index 6813f7b5..1e09f670 100644 --- a/scripts/environment/setup.bash +++ b/scripts/environment/setup.bash @@ -1,8 +1,9 @@ usage='setup.bash "ros_distro" "ros_ws_suffix" "workspace_folder"' # Load Framework defines -# script_own_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" -# source $script_own_dir/../_RosTeamWs_Defines.bash +script_own_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" +source $script_own_dir/../_RosTeamWs_Defines.bash +source $script_own_dir/../_Team_Defines.bash # ros distribution name will be set in $ros_distro check_ros_distro $1 @@ -21,22 +22,34 @@ fi unset CMAKE_PREFIX_PATH unset ROS_PACKAGE_PATH -unset COLCON_WS +unset ROS_WS if [[ $ros_version == 1 ]]; then + setup_aliases setup_ros1_exports setup_ros1_aliases - source ~/$ws_folder/ros_ws_$ros_distro$ws_suffix/devel/setup.bash - source `rospack find intelligent_robotic_automation`/scripts/environment/ros_setup.bash + WS_FOLDER="$HOME/$ws_folder/ros_ws_$ros_distro$ws_suffix" + + if [ ! -d "$WS_FOLDER" ]; then + print_and_exit print_and_exit "'$WS_FOLDER_1' does not exist. Can not find ROS workspace!" + fi + + export ROS_WS=$WS_FOLDER + source "$WS_FOLDER/devel/setup.bash" + + echo "" + echo "RosTeamWS: Sourced file: $WS_FOLDER/devel/setup.bash" + elif [[ $ros_version == 2 ]]; then + setup_aliases setup_ros2_exports setup_ros2_aliases - /opt/rti.com/rti_connext_dds-5.3.1/setenv_ros2rti.bash +# /opt/rti.com/rti_connext_dds-5.3.1/setenv_ros2rti.bash # export LANG=de_DE.UTF-8 WS_FOLDER="" WS_FOLDER_1="$HOME/$ws_folder/ros_ws_$ros_distro$ws_suffix" @@ -46,10 +59,12 @@ elif [[ $ros_version == 2 ]]; then elif [ -d "$WS_FOLDER_2" ]; then WS_FOLDER=$WS_FOLDER_2 else - print_and_exit "Neither '$WS_FOLDER_1' nor 'WS_FOLDER_2' exist. Can not find ROS workspace!" + print_and_exit "Neither '$WS_FOLDER_1' nor '$WS_FOLDER_2' exist. Can not find ROS workspace!" fi - export COLCON_WS=$WS_FOLDER + export ROS_WS=$WS_FOLDER + # TODO: COLCON_WS is deprecated!! + export COLCON_WS=$ROS_WS source "$WS_FOLDER/install/setup.bash" echo "" diff --git a/scripts/os_configure/install_software_20.bash b/scripts/os_configure/install_software_20.bash new file mode 100644 index 00000000..00e3a10f --- /dev/null +++ b/scripts/os_configure/install_software_20.bash @@ -0,0 +1,130 @@ +#!/usr/bin/bash +# +# install_software_20.bash [computer_type:{office, robot, default:lab}] +# + +script_own_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" +SCRIPT_PATH=$script_own_dir + +computer_type=$1 +if [ -z "$1" ] +then + computer_type="lab" + echo "Computer type not provided using default $computer_type" +fi + +echo "Installing software for $computer_type computers. Press to continue." +read + +ROS_VERSION=melodic +ROS2_VERSION=foxy + +#KDE Backports +sudo apt-add-repository -y ppa:kubuntu-ppa/backports +sudo apt update && sudo apt -y dist-upgrade && sudo apt -y autoremove + +### Usefull tools +sudo apt -y install vim ssh git trash-cli htop unrar yakuake screen finger ksshaskpass kompare +# Dolphin Plugins +sudo apt -y install kdesdk-dolphin-plugins kdesdk-kio-plugins kdesdk-scripts + +if ([[ $computer_type != "robot" ]]) +then + sudo apt -y install recordmydesktop rdesktop gimp gimp-ufraw meshlab inkscape pdfposter unrar + sudo DEBIAN_FRONTEND=noninteractive apt -y install wireshark + sudo apt -y install gvfs-bin gvfs-fuse gvfs-backends +fi + +# Usefull libraries +sudo apt -y install libxml2-dev + +if ([[ $computer_type != "robot" ]]) +then + # Latex + sudo apt -y install kile texlive-full texlive-lang-german kbibtex ktikz +fi + +# Libraries +sudo apt -y install libvlc-dev libmuparser-dev + +# Python tools +sudo apt -y install python3-pip +sudo pip3 install --upgrade pip +sudo pip3 install virtualenv virtualenvwrapper notebook + + +# ROS Packages +bash $SCRIPT_PATH/install_software_ros.bash $ROS_VERSION + +# ROS2 Packages +bash $SCRIPT_PATH/install_software_ros2.bash $ROS2_VERSION + +sudo rosdep init +rosdep update + +# if ([[ $computer_type == "lab" ]] || [[$computer_type == "robot" ]]) +# then +# bash $SCRIPT_PATH/configure_ROSTeamWS.bash $ROS_VERSION +# fi +# +# if ([[ $computer_type == "robot" ]]) +# then +# bash $SCRIPT_PATH/configure_robots.bash $ROS_VERSION +# fi + +if ([[ $computer_type == "office" ]]) +then + sudo apt -y install redshift + + #Nvidia drivers +# sudo add-apt-repository -y ppa:graphics-drivers/ppa +# sudo apt update +# sudo apt -y install nvidia-396 + + # Network manager + sudo apt -y install network-manager-openvpn network-manager-vpnc network-manager-ssh network-manager-openconnect + + sudo apt -y install kleopatra scdaemon + #see: #13 at https://bugs.launchpad.net/kubuntu-ppa/+bug/684902 +# echo 'use-agent' >> .gnupg/gpg.conf + + # Datensicherung +# sudo apt -y install kup bup + + sudo apt -y install flac + + sudo add-apt-repository -y ppa:freecad-maintainers/freecad-daily + sudo apt update + sudo apt -y install freecad-daily spacenavd + + #NextCloud + sudo add-apt-repository -y ppa:nextcloud-devs/client + sudo apt update + sudo apt -y install nextcloud-client + + #VirtualBox + sudo sh -c 'echo "deb [arch=amd64] https://download.virtualbox.org/virtualbox/debian $(lsb_release -sc) contrib" > /etc/apt/sources.list.d/virtualbox.list' + wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - + sudo apt update + sudo apt -y install virtualbox-6.1 dkms virtualbox-guest-utils virtualbox-ext-pack + + # Hamsket + sudo apt -y install libappindicator3-1 + wget https://github.com/TheGoddessInari/hamsket/releases/download/0.6.2/hamsket_0.6.2_amd64.deb + sudo dpkg -i hamsket_0.6.2_amd64.deb + + # KDE-PIM + sudo apt -y install kontact korganizer kmail kjots kaddressbook kdepim* + + # Tools + sudo apt -y install kdrc + +fi + +sudo apt update && sudo apt -y dist-upgrade && sudo apt -y autoremove + + +# Configs +# Yakuake + + diff --git a/scripts/os_configure/install_software_ros.bash b/scripts/os_configure/install_software_ros.bash new file mode 100644 index 00000000..b515a218 --- /dev/null +++ b/scripts/os_configure/install_software_ros.bash @@ -0,0 +1,78 @@ +#!/usr/bin/bash + +#### ROS Repository +sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' +sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 +sudo apt update + +ROS_DISTRO=$1 +if [ -z "$1" ] +then + ROS_DISTRO=noetic + echo "Ros version not provided! Using default distribution \"${ROS_DISTRO}\"" + echo "Press to continue..." + read +fi + +# Build Essentials +sudo apt -y install build-essential + +# Libraries +sudo apt -y install libgoogle-glog-dev libatlas-base-dev + +# ROS Base +sudo apt -y install ros-${ROS_DISTRO}-desktop-full ros-${ROS_DISTRO}-desktop ros-${ROS_DISTRO}-simulators + +# ROS: Usefull tools +sudo apt -y install python3-catkin-* +sudo apt install python3-catkin-lint python3-pip +sudo pip3 install osrf-pycommon +sudo apt -y install python3-wstool +sudo apt -y install python3-vcstool +sudo apt -y install clang-format +sudo apt -y install python3-rosinstall rospack-tools + +sudo apt -y install ros-${ROS_DISTRO}-rospy-message-converter + +sudo apt -y install ros-${ROS_DISTRO}-rosparam-handler + +# ROS: Visualisation +sudo apt -y install ros-${ROS_DISTRO}-rqt-* +sudo apt -y install ros-${ROS_DISTRO}-plotjuggler-ros + +# ROS: Robot packages +sudo apt -y install ros-${ROS_DISTRO}-cob-* +sudo apt -y install ros-${ROS_DISTRO}-moveit +sudo apt -y install ros-${ROS_DISTRO}-moveit-* +sudo apt -y install libmuparser-dev ros-${ROS_DISTRO}-brics-actuator ros-${ROS_DISTRO}-openrave ros-${ROS_DISTRO}-move-base +sudo apt -y install ros-${ROS_DISTRO}-teleop-twist-joy ros-${ROS_DISTRO}-twist-mux +# Mit dem vorsicht auch: ros-${ROS_DISTRO}-schunk-* + +# INSTALL Released repos from KITRobotics +# sudo apt -y install ros-${ROS_DISTRO}-iirob-filters ros-${ROS_DISTRO}-force-torque-sensor ros-${ROS_DISTRO}-ati-force-torque +# sudo apt -y install ros-${ROS_DISTRO}-ipr-extern + + +# ROS Control +sudo apt -y install ros-${ROS_DISTRO}-control-* +sudo apt -y install ros-${ROS_DISTRO}-ros-control* +sudo apt -y install ros-${ROS_DISTRO}-ros-control ros-${ROS_DISTRO}-position-controllers ros-${ROS_DISTRO}-velocity-controllers ros-${ROS_DISTRO}-joint-trajectory-controller ros-${ROS_DISTRO}-joint-state-controller + +sudo apt -y install ros-${ROS_DISTRO}-gazebo-ros-control ros-${ROS_DISTRO}-four-wheel-steering-msgs ros-${ROS_DISTRO}-urdf-geometry-parser ros-${ROS_DISTRO}-base-local-planner + +# ROS Industrial +sudo apt -y install ros-${ROS_DISTRO}-industrial-robot-client + +# ROS: Additional packages +sudo apt -y install ros-${ROS_DISTRO}-rosparam-handler ros-${ROS_DISTRO}-pcl-ros ros-${ROS_DISTRO}-opencv3 ros-${ROS_DISTRO}-srdfdom ros-${ROS_DISTRO}-warehouse-ros + +# TF2 Packages +sudo apt -y install ros-${ROS_DISTRO}-tf2 ros-${ROS_DISTRO}-tf2-sensor-msgs + +# IKFast and OpenRAVE +# sudo add-apt-repository ppa:openrave/release +# sudo apt update +# sudo apt install openrave0.8-dp-ikfast + +# Add libraris for ROS packages +#sudo apt -y install libfcl-dev libfcl-0.5-dev diff --git a/scripts/os_configure/install_software_ros2.bash b/scripts/os_configure/install_software_ros2.bash new file mode 100644 index 00000000..a2ce4a50 --- /dev/null +++ b/scripts/os_configure/install_software_ros2.bash @@ -0,0 +1,49 @@ +#!/usr/bin/bash +# based on https://index.ros.org/doc/ros2/Installation/Foxy/Linux-Development-Setup/ + +ROS_DISTRO=$1 +if [ -z "$1" ] +then + ROS_DISTRO=${ROS_DISTRO} + echo "ROS2 version not specified! Using default distribution \"${ROS_DISTRO}\"" + echo "Press to continue..." + read +fi + +sudo apt update && sudo apt -y install curl gnupg2 lsb-release +curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - +sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2-latest.list' + +sudo apt update + +# ROS: Usefull tools +sudo apt -y install python3-vcstool + +sudo apt -y install ros-${ROS_DISTRO}-desktop + +# sudo apt install -y python3-pip +# sudo pip3 install -U argcomplete +# sudo pip3 install -U rosdep + +# echo "ROS1 - ROS2 bridge also gets installed" +# echo "Press to continue..." +# read # probably to be removed later +# sudo apt install -y ros-${ROS_DISTRO}-ros1-bridge + +sudo apt install -y python3-colcon-common-extensions #Install colcon for workspace creation + + +sudo apt install ccache + +sudo apt install python3-colcon-mixin +colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml +colcon mixin update default + +# visualizations +sudo apt -y install ros-${ROS_DISTRO}-plotjuggler-ros + +# ros2_control +sudo apt -y install ros-${ROS_DISTRO}-forward-command-controller ros-${ROS_DISTRO}-joint-state-controller ros-${ROS_DISTRO}-joint-trajectory-controller ros-${ROS_DISTRO}-xacro + +# MoveIt +sudo apt -y install ros-${ROS_DISTRO}-geometric-shapes ros-${ROS_DISTRO}-moveit-msgs ros-${ROS_DISTRO}-moveit-resources ros-${ROS_DISTRO}-srdfdom ros-${ROS_DISTRO}-warehouse-ros diff --git a/scripts/ros2_control/setup-controller-package.bash b/scripts/ros2_control/setup-controller-package.bash index 0327c4f4..aa100de2 100755 --- a/scripts/ros2_control/setup-controller-package.bash +++ b/scripts/ros2_control/setup-controller-package.bash @@ -75,6 +75,9 @@ case "$choice" in LICENSE_HEADER="$LICENSE_TEMPLATES/propriatery_company_cpp.txt" esac +read -p "Is package already configured? (yes/no) [no] " package_configured +package_configured=${package_configured:="no"} + echo "" echo "ATTENTION: Setting up ros2_control controller files with following parameters: file name '$FILE_NAME', class '$CLASS_NAME', package/namespace '$PKG_NAME'. Those will be placed in folder '`pwd`'." echo "" @@ -95,10 +98,12 @@ PLUGIN_XML="$PKG_NAME.xml" TEST_CPP="test/test_load_$FILE_NAME.cpp" # Copy files -cp -n $ROS2_CONTROL_HW_ITF_TEMPLATES/visibility_control.h $VC_H +if [[ ! -f "$VC_H" ]]; then + cp -n $ROS2_CONTROL_HW_ITF_TEMPLATES/visibility_control.h $VC_H +fi +cat $ROS2_CONTROL_CONTROLLER_TEMPLATES/controller_pluginlib.xml >> $PLUGIN_XML cp -n $ROS2_CONTROL_CONTROLLER_TEMPLATES/controller.hpp $CTRL_HPP cp -n $ROS2_CONTROL_CONTROLLER_TEMPLATES/controller.cpp $CTRL_CPP -cp -n $ROS2_CONTROL_CONTROLLER_TEMPLATES/controller_pluginlib.xml $PLUGIN_XML cp -n $ROS2_CONTROL_CONTROLLER_TEMPLATES/test_load_controller.cpp $TEST_CPP echo "Template files copied." @@ -110,7 +115,10 @@ echo "Template files copied." # list(APPEND AMENT_LINT_AUTO_EXCLUDE # ament_cmake_copyright # ) -FILES_TO_LICENSE=($VC_H $CTRL_HPP $CTRL_CPP $TEST_CPP) +FILES_TO_LICENSE=("$CTRL_HPP" "$CTRL_CPP" "$TEST_CPP") +if [[ "$package_configured" == "no" ]]; then + FILES_TO_LICENSE+=("$VC_H") +fi TMP_FILE=".f_tmp" if [[ "$LICENSE_HEADER" != "" ]]; then touch $TMP_FILE @@ -125,8 +133,8 @@ if [[ "$LICENSE_HEADER" != "" ]]; then # echo "Licence header added to files: ("`declare -p FILES_TO_LICENSE`")" fi -FILES_TO_SED=("${FILES_TO_LICENSE[@]}") # sed all needed files +FILES_TO_SED=("${FILES_TO_LICENSE[@]}") FILES_TO_SED+=("$PLUGIN_XML") # declare -p FILES_TO_SED @@ -183,26 +191,30 @@ echo ")" >> $TMP_FILE echo "# prevent pluginlib from using boost" >> $TMP_FILE echo "target_compile_definitions($PKG_NAME PUBLIC \"PLUGINLIB__DISABLE_BOOST_FUNCTIONS\")" >> $TMP_FILE -echo "" >> $TMP_FILE -echo "pluginlib_export_plugin_description_file(" >> $TMP_FILE -echo " controller_interface $PLUGIN_XML)" >> $TMP_FILE +if [[ "$package_configured" == "no" ]]; then -## Add install directives -echo "" >> $TMP_FILE -echo "install(" >> $TMP_FILE -echo " TARGETS" >> $TMP_FILE -echo " $PKG_NAME" >> $TMP_FILE -echo " RUNTIME DESTINATION bin" >> $TMP_FILE -echo " ARCHIVE DESTINATION lib" >> $TMP_FILE -echo " LIBRARY DESTINATION lib" >> $TMP_FILE -echo ")" >> $TMP_FILE + echo "" >> $TMP_FILE + echo "pluginlib_export_plugin_description_file(" >> $TMP_FILE + echo " controller_interface $PLUGIN_XML)" >> $TMP_FILE -if [[ ! `grep -q "DIRECTORY include/" $TMP_FILE` ]]; then + ## Add install directives echo "" >> $TMP_FILE echo "install(" >> $TMP_FILE - echo " DIRECTORY include/" >> $TMP_FILE - echo " DESTINATION include" >> $TMP_FILE + echo " TARGETS" >> $TMP_FILE + echo " $PKG_NAME" >> $TMP_FILE + echo " RUNTIME DESTINATION bin" >> $TMP_FILE + echo " ARCHIVE DESTINATION lib" >> $TMP_FILE + echo " LIBRARY DESTINATION lib" >> $TMP_FILE echo ")" >> $TMP_FILE + + if [[ ! `grep -q "DIRECTORY include/" $TMP_FILE` ]]; then + echo "" >> $TMP_FILE + echo "install(" >> $TMP_FILE + echo " DIRECTORY include/" >> $TMP_FILE + echo " DESTINATION include" >> $TMP_FILE + echo ")" >> $TMP_FILE + fi + fi echo "" >> $TMP_FILE @@ -225,23 +237,27 @@ echo "" # Add export definitions tail -n +$TEST_LINE CMakeLists.txt | head -$END_TEST_LINE | tail -1 >> $TMP_FILE -echo "" >> $TMP_FILE -echo "ament_export_include_directories(" >> $TMP_FILE -echo " include" >> $TMP_FILE -echo ")" >> $TMP_FILE +if [[ "$package_configured" == "no" ]]; then -echo "ament_export_libraries(" >> $TMP_FILE -echo " $PKG_NAME" >> $TMP_FILE -echo ")" >> $TMP_FILE + echo "" >> $TMP_FILE + echo "ament_export_include_directories(" >> $TMP_FILE + echo " include" >> $TMP_FILE + echo ")" >> $TMP_FILE -# TODO(anyone): use this from a list so its the same as above -echo "ament_export_dependencies(" >> $TMP_FILE -echo " controller_interface" >> $TMP_FILE -echo " hardware_interface" >> $TMP_FILE -echo " pluginlib" >> $TMP_FILE -echo " rclcpp" >> $TMP_FILE -echo " rclcpp_lifecycle" >> $TMP_FILE -echo ")" >> $TMP_FILE + echo "ament_export_libraries(" >> $TMP_FILE + echo " $PKG_NAME" >> $TMP_FILE + echo ")" >> $TMP_FILE + + # TODO(anyone): use this from a list so its the same as above + echo "ament_export_dependencies(" >> $TMP_FILE + echo " controller_interface" >> $TMP_FILE + echo " hardware_interface" >> $TMP_FILE + echo " pluginlib" >> $TMP_FILE + echo " rclcpp" >> $TMP_FILE + echo " rclcpp_lifecycle" >> $TMP_FILE + echo ")" >> $TMP_FILE + +fi # Add last part let CUT_LINE=$END_TEST_LINE+1 diff --git a/scripts/setup-repository.bash b/scripts/setup-repository.bash index 96c724d3..32b16484 100755 --- a/scripts/setup-repository.bash +++ b/scripts/setup-repository.bash @@ -73,6 +73,7 @@ case "$choice" in cp -n $PACKAGE_TEMPLATES/CI-github_ci-lint.yml .github/workflows/ci-lint.yml sed -i 's/\$NAME\$/'${PKG_NAME}'/g' .github/workflows/ci-lint.yml cp -n $PACKAGE_TEMPLATES/pkg_name.repos $PKG_NAME.repos + ln -s $PKG_NAME.repos $PKG_NAME.ci.repos echo "NOTE: To enable CI from source, uncomment it manually in '.github/workflows/ci-build.yml'" cp -n $PACKAGE_TEMPLATES/README.md.github README.md repository="github" diff --git a/scripts/setup-ros-workspace.bash b/scripts/setup-ros-workspace.bash index e5e43dfc..65056488 100755 --- a/scripts/setup-ros-workspace.bash +++ b/scripts/setup-ros-workspace.bash @@ -111,4 +111,4 @@ if [[ $ros_version == 1 ]]; then fi echo "------------------------------------------------------" -echo "Fnished: Please open a new terminal and execute '$alias_name'" +echo "Finished: Please open a new terminal and execute '$alias_name'" diff --git a/setup.bash b/setup.bash index 10a9e5d8..13563c2b 100644 --- a/setup.bash +++ b/setup.bash @@ -1,4 +1,5 @@ script_own_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" +FRAMEWORK_BASE_PATH=$script_own_dir # Load RosTeamWS defines source $script_own_dir/scripts/_RosTeamWs_Defines.bash @@ -6,6 +7,7 @@ source $script_own_dir/scripts/_RosTeamWs_Defines.bash # Load Team defines source $script_own_dir/scripts/_Team_Defines.bash - # Set main path where source.bash is defined -RosTeamWS_FRAMEWORK_MAIN_PATH=$(RosTeamWS_script_own_dir) +RosTeamWS_FRAMEWORK_MAIN_PATH="$(RosTeamWS_script_own_dir)/../" + +framework_default_paths $DEFAULT_ROS_DISTRO diff --git a/templates/package/CI-github_ci-build.yml b/templates/package/CI-github_ci-build.yml index 0571eb34..b498674c 100644 --- a/templates/package/CI-github_ci-build.yml +++ b/templates/package/CI-github_ci-build.yml @@ -18,7 +18,7 @@ jobs: - {ROS_DISTRO: $ROS_DISTRO$, ROS_REPO: main} - {ROS_DISTRO: $ROS_DISTRO$, ROS_REPO: testing} env: - UPSTREAM_WORKSPACE: $NAME$.repos + UPSTREAM_WORKSPACE: $NAME$.ci.repos steps: - uses: actions/checkout@v1 - uses: 'ros-industrial/industrial_ci@master' diff --git a/templates/package/CI-github_docs-sphinx-build-check.yml b/templates/package/CI-github_docs-sphinx-build-check.yml index 7e89a8e9..9de5802d 100644 --- a/templates/package/CI-github_docs-sphinx-build-check.yml +++ b/templates/package/CI-github_docs-sphinx-build-check.yml @@ -3,17 +3,16 @@ on: pull_request: push: branches: - - main + - $ROS_DISTRO$ schedule: - # Run every morning to detect flakiness and broken dependencies + # Run every day to detect flakiness and broken dependencies - cron: '23 5 * * *' jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: ammaraskar/sphinx-action@master + - uses: ros-controls/control.ros.org-deployment-scripts@master with: - docs-folder: '$DOCS_FOLDER$' - pre-build-command: "apt-get update -y && apt-get install -y python3-pip && pip3 install sphinx_rtd_theme" + install_extensions: false + diff --git a/templates/package/CI-github_docs-sphinx-make-page.yml b/templates/package/CI-github_docs-sphinx-make-page.yml index f85b5711..f47a7a36 100644 --- a/templates/package/CI-github_docs-sphinx-make-page.yml +++ b/templates/package/CI-github_docs-sphinx-make-page.yml @@ -1,17 +1,17 @@ -name: "Generate Docs Page" +name: "Build & Deploy Page" on: push: branches: - - main + - $ROS_DISTRO$ jobs: build: - name: Push Sphinx Pages runs-on: ubuntu-latest steps: - - uses: seanzhengw/sphinx-pages@master + - uses: ros-controls/control.ros.org-deployment-scripts@master with: - create_readme: true github_token: ${{ secrets.GITHUB_TOKEN }} + create_readme: true install_extensions: false + deploy: true source_dir: '$DOCS_FOLDER$' diff --git a/templates/robot_description/robot.urdf.xacro b/templates/robot_description/robot.urdf.xacro index 219c986f..02bee333 100644 --- a/templates/robot_description/robot.urdf.xacro +++ b/templates/robot_description/robot.urdf.xacro @@ -4,6 +4,7 @@ + @@ -13,13 +14,13 @@ - + diff --git a/templates/robot_description/robot_macro.ros2_control.xacro b/templates/robot_description/robot_macro.ros2_control.xacro index 58743d52..461dc903 100644 --- a/templates/robot_description/robot_macro.ros2_control.xacro +++ b/templates/robot_description/robot_macro.ros2_control.xacro @@ -6,8 +6,9 @@ - fake_components/GenericRobot + fake_components/GenericSystem ${fake_sensor_commands} + 0.0 robot_hardware_inteface/RobotHardwareInteface diff --git a/templates/robot_description/robot_macro.xacro b/templates/robot_description/robot_macro.xacro index b4f782fe..2f1271a8 100644 --- a/templates/robot_description/robot_macro.xacro +++ b/templates/robot_description/robot_macro.xacro @@ -150,14 +150,14 @@ - + - + @@ -224,7 +224,7 @@ - + @@ -238,7 +238,7 @@ - + diff --git a/templates/robot_description/test_robot_description.launch.py b/templates/robot_description/test_robot_description.launch.py index b19a5517..bbae3d3b 100644 --- a/templates/robot_description/test_robot_description.launch.py +++ b/templates/robot_description/test_robot_description.launch.py @@ -1,31 +1,46 @@ $LICENSE$ -import os - -from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription -from launch_ros.actions import Node +from launch.actions import DeclareLaunchArgument +from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution -import xacro +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare def generate_launch_description(): + # Declare arguments + declared_arguments = [] + declared_arguments.append(DeclareLaunchArgument( + 'description_package', default_value='$PKG_NAME$', + description='Description package of the $ROBOT_NAME$. Usually the argument is not set, \ + it enables use of a custom description.')) + declared_arguments.append(DeclareLaunchArgument( + 'prefix', default_value='""', description='Prefix of the joint names, useful for \ + multi-robot setup. If changed than also joint names in the controllers\' configuration \ + have to be updated.')) + + # Initialize Arguments + description_package = LaunchConfiguration('description_package') + prefix = LaunchConfiguration('prefix') # Get URDF via xacro - robot_description_path = os.path.join( - get_package_share_directory('$PKG_NAME$'), - 'urdf', - '$ROBOT_NAME$.urdf.xacro') - robot_description_config = xacro.process_file(robot_description_path, - mappings={'fake_sensor_commands': 'true'}) - robot_description = {'robot_description': robot_description_config.toxml()} - - rviz_config_file = os.path.join( - get_package_share_directory('$PKG_NAME$'), + robot_description_content = Command([ + PathJoinSubstitution([FindExecutable(name='xacro')]), + ' ', + PathJoinSubstitution([FindPackageShare(description_package), + 'urdf', '$ROBOT_NAME$.urdf.xacro']), + ' ', + 'prefix:=', prefix, ' ', + ]) + + robot_description = {'robot_description': robot_description_content} + + rviz_config_file = PathJoinSubstitution([ + FindPackageShare(description_package), 'rviz', '$ROBOT_NAME$.rviz' - ) + ]) joint_state_publisher_node = Node( package='joint_state_publisher_gui', @@ -45,8 +60,10 @@ def generate_launch_description(): arguments=['-d', rviz_config_file], ) - return LaunchDescription([ - joint_state_publisher_node, - robot_state_publisher_node, - rviz_node, - ]) + return LaunchDescription( + declared_arguments + + [ + joint_state_publisher_node, + robot_state_publisher_node, + rviz_node, + ]) diff --git a/templates/ros2_control/controller/controller_pluginlib.xml b/templates/ros2_control/controller/controller_pluginlib.xml index 218427ba..84d38cf3 100644 --- a/templates/ros2_control/controller/controller_pluginlib.xml +++ b/templates/ros2_control/controller/controller_pluginlib.xml @@ -2,7 +2,7 @@ - ros2_control controller. + $ClassName$ ros2_control controller. diff --git a/templates/ros2_control/robot_ros2_control.launch.py b/templates/ros2_control/robot_ros2_control.launch.py index 2701a4b5..b9d48fd9 100644 --- a/templates/ros2_control/robot_ros2_control.launch.py +++ b/templates/ros2_control/robot_ros2_control.launch.py @@ -1,47 +1,75 @@ $LICENSE$ -import os - -from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription -from launch_ros.actions import Node +from launch.actions import DeclareLaunchArgument, ExecuteProcess +from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution -import xacro +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare def generate_launch_description(): + # Declare arguments + declared_arguments = [] + declared_arguments.append(DeclareLaunchArgument( + 'controllers_package', default_value='ros2_control_demo_robot', + description='Package with the controller\'s configuration in "config" folder. \ + Usually the argument is not set, it enables use of a custom description.')) + declared_arguments.append(DeclareLaunchArgument( + 'description_package', default_value='ros2_control_demo_robot', + description='Description package with robot URDF/xacro files. Usually the argument \ + is not set, it enables use of a custom description.')) + declared_arguments.append(DeclareLaunchArgument( + 'prefix', default_value='""', description='Prefix of the joint names, useful for \ + multi-robot setup. If changed than also joint names in the controllers\' configuration \ + have to be updated.')) + declared_arguments.append(DeclareLaunchArgument( + 'use_fake_hardware', default_value='true', + description='Start robot with fake hardware mirroring command to its states.')) + declared_arguments.append(DeclareLaunchArgument( + 'fake_sensor_commands', default_value='false', + description='Enable fake command interfaces for sensors used for simple simulations. \ + Used only if \'use_fake_hardware\' parameter is true.')) + + # Initialize Arguments + controllers_package = LaunchConfiguration('controllers_package') + description_package = LaunchConfiguration('description_package') + prefix = LaunchConfiguration('prefix') + use_fake_hardware = LaunchConfiguration('use_fake_hardware') + fake_sensor_commands = LaunchConfiguration('fake_sensor_commands') # Get URDF via xacro - robot_description_path = os.path.join( - get_package_share_directory('$DESCR_PKG_NAME$'), - 'urdf', - '$ROBOT_NAME$.urdf.xacro') - robot_description_config = xacro.process_file(robot_description_path, - mappings={ - 'use_fake_hardware': 'true', - 'fake_sensor_commands': 'true' - }) - robot_description = {'robot_description': robot_description_config.toxml()} + robot_description_content = Command([ + PathJoinSubstitution([FindExecutable(name='xacro')]), + ' ', + PathJoinSubstitution([FindPackageShare(description_package), + 'description', '$ROBOT_NAME$.urdf.xacro']), + ' ', + 'prefix:=', prefix, ' ', + 'use_fake_hardware:=', use_fake_hardware, ' ', + 'fake_sensor_commands:=', fake_sensor_commands, ' ', + ]) + + robot_description = {'robot_description': robot_description_content} - robot_controllers = os.path.join( - get_package_share_directory('$PKG_NAME$'), + robot_controllers = PathJoinSubstitution([ + FindPackageShare(controllers_package), 'config', '$ROBOT_NAME$_controllers.yaml' - ) - rviz_config_file = os.path.join( - get_package_share_directory('$DESCR_PKG_NAME$'), + ]) + rviz_config_file = PathJoinSubstitution([ + FindPackageShare(description_package), 'rviz', '$ROBOT_NAME$.rviz' - ) + ]) control_node = Node( - package='controller_manager', - executable='ros2_control_node', - parameters=[robot_description, robot_controllers], - output={ - 'stdout': 'screen', - 'stderr': 'screen', + package='controller_manager', + executable='ros2_control_node', + parameters=[robot_description, robot_controllers], + output={ + 'stdout': 'screen', + 'stderr': 'screen', }, ) robot_state_pub_node = Node( @@ -58,8 +86,19 @@ def generate_launch_description(): arguments=['-d', rviz_config_file], ) - return LaunchDescription([ - control_node, - robot_state_pub_node, - rviz_node, - ]) + robot_controller = 'forward_position_controller' + # robot_controller = 'joint_trajectory_controller' + robot_controller_spawner = Node( + package='controller_manager', + executable='spawner.py', + arguments=[robot_controller, '-c', '/controller_manager']) + + return LaunchDescription( + declared_arguments + + [ + control_node, + robot_state_pub_node, + rviz_node, + joint_state_controller_spawner, + robot_controller_spawner, + ]) diff --git a/templates/ros2_control/test_forward_position_controller.launch.py b/templates/ros2_control/test_forward_position_controller.launch.py index abba3d71..e6f5b6d8 100644 --- a/templates/ros2_control/test_forward_position_controller.launch.py +++ b/templates/ros2_control/test_forward_position_controller.launch.py @@ -1,20 +1,18 @@ $LICENSE$ -import os - -from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription +from launch.substitutions import PathJoinSubstitution from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare def generate_launch_description(): - position_goals = os.path.join( - get_package_share_directory('$PKG_NAME$'), + position_goals = PathJoinSubstitution([ + FindPackageShare('$PKG_NAME$'), 'config', '$ROBOT_NAME$_forward_position_publisher.yaml' - ) + ]) return LaunchDescription([ Node( diff --git a/templates/ros2_control/test_joint_trajectory_controller.launch.py b/templates/ros2_control/test_joint_trajectory_controller.launch.py index dfc5fb0a..6d70cef7 100644 --- a/templates/ros2_control/test_joint_trajectory_controller.launch.py +++ b/templates/ros2_control/test_joint_trajectory_controller.launch.py @@ -1,20 +1,18 @@ $LICENSE$ -import os - -from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription +from launch.substitutions import PathJoinSubstitution from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare def generate_launch_description(): - position_goals = os.path.join( - get_package_share_directory('$PKG_NAME$'), + position_goals = PathJoinSubstitution([ + FindPackageShare('$PKG_NAME$'), 'config', '$ROBOT_NAME$_joint_trajectory_publisher.yaml' - ) + ]) return LaunchDescription([ Node(