diff --git a/.github/scripts/install_dls2_msgs.sh b/.github/scripts/install_dls2_msgs.sh index 0446cb6..65cb6d1 100755 --- a/.github/scripts/install_dls2_msgs.sh +++ b/.github/scripts/install_dls2_msgs.sh @@ -23,8 +23,8 @@ if [ -z "$TOKEN" ]; then fi export GH_TOKEN="$TOKEN" -# Resolve the dls2_msgs submodule commit SHA pinned in this repo -SHA="$(git -C "$(dirname "${BASH_SOURCE[0]}")/../.." ls-tree HEAD dls2_msgs | awk '{print $3}')" +# Resolve the dls2_msgs submodule commit SHA pinned in transport_interfaces +SHA="$(git -C "$(dirname "${BASH_SOURCE[0]}")/../../transport_interfaces" ls-tree HEAD transports/fastdds/dls2_msgs | awk '{print $3}')" echo "dls2_msgs submodule is pinned to commit: $SHA" # Find the release tag that points to that commit diff --git a/.gitmodules b/.gitmodules index af4163c..65ccd38 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,4 +12,10 @@ url = https://github.com/iit-DLSLab/dls2_msgs.git [submodule "pinocchio-gluecode"] path = pinocchio-gluecode - url = https://github.com/iit-DLSLab/pinocchio-gluecode.git \ No newline at end of file + url = https://github.com/iit-DLSLab/pinocchio-gluecode.git +[submodule "transport_interfaces"] + path = transport_interfaces + url = git@github.com:iit-DLSLab/transport_interfaces.git +[submodule "dls_hal"] + path = dls_hal + url = git@github.com:iit-DLSLab/dls_hal.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f53b7b..661c816 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,40 +6,22 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() -set(DLS_MESSAGE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/dls2_msgs - CACHE PATH "Path to the dls2_msgs folder" -) -add_subdirectory(dls2) -option(BUILD_DLS2_MSGS "Build the dls2_msgs submodule. Disable when dls2_msgs is pre-installed (e.g. in CI)." ON) -if(BUILD_DLS2_MSGS) - add_subdirectory(dls2_msgs) +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/dls_message_paths.cmake") + +if(NOT CMAKE_INSTALL_RPATH) + set(CMAKE_INSTALL_RPATH "/opt/dls2/lib;/opt/dls2/hardwares/lib" CACHE STRING "RPATH for installed binaries" FORCE) endif() + +add_subdirectory(transport_interfaces) +add_subdirectory(dls_hal) +add_subdirectory(dls2) add_subdirectory(robotlib) add_subdirectory(pinocchio-gluecode) add_subdirectory(visualizers/rviz_interface) -# generate ROS2 messages from IDL files each time CMake is run, to ensure they are always up to date with the IDL definitions -message(STATUS "Generating ROS2 messages from IDL files...") -set (DLS2_ROS2_INTERFACE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dls2_ros2_interface/ros2_ws/src) -set (DLS2_ROS2_INTERFACE_DIR ${DLS2_ROS2_INTERFACE_SRC_DIR}/dls2_interface) - - -# remove .msg files from the ROS2 interface src directory to avoid conflicts with the newly generated ones -file(GLOB DLS_MSG_FILES CONFIGURE_DEPENDS "${DLS2_ROS2_INTERFACE_DIR}/msg/*.msg") -foreach(msg_file IN LISTS DLS_MSG_FILES) - file(REMOVE ${msg_file}) -endforeach() - -file(GLOB DLS_IDL_FILES CONFIGURE_DEPENDS "${DLS_MESSAGE_FOLDER}/idls/*.idl") -foreach(idl_file IN LISTS DLS_IDL_FILES) - execute_process( - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${DLS2_ROS2_INTERFACE_DIR}/scripts ${DLS2_ROS2_INTERFACE_DIR}/scripts/idl_to_msg.py ${idl_file} -o ${DLS2_ROS2_INTERFACE_SRC_DIR}/ - WORKING_DIRECTORY ${DLS2_ROS2_INTERFACE_DIR} - RESULT_VARIABLE result - ) -endforeach() +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate_ros2_messages.cmake") # install setup_ros2_for_dls2.bash install(FILES dls2_ros2_interface/ros2_ws/src/dls2_interface/scripts/setup_ros2_for_dls2.bash DESTINATION /usr/bin/dls2/scripts/ -) \ No newline at end of file +) diff --git a/cmake/dls_message_paths.cmake b/cmake/dls_message_paths.cmake new file mode 100644 index 0000000..79a1a2e --- /dev/null +++ b/cmake/dls_message_paths.cmake @@ -0,0 +1,10 @@ +# Configure the IDL source directory before adding dependent subdirectories. +set(DLS_MESSAGE_DEFAULT_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/transport_interfaces/transports/fastdds/dls2_msgs") +set(DLS_MESSAGE_FOLDER "${DLS_MESSAGE_DEFAULT_FOLDER}" + CACHE PATH "Path to the dls2_msgs folder" +) +# Older build caches can still point to the former dls2_msgs location. +if(NOT IS_DIRECTORY "${DLS_MESSAGE_FOLDER}/idls") + message(WARNING "DLS_MESSAGE_FOLDER '${DLS_MESSAGE_FOLDER}' has no idls directory; using '${DLS_MESSAGE_DEFAULT_FOLDER}'.") + set(DLS_MESSAGE_FOLDER "${DLS_MESSAGE_DEFAULT_FOLDER}" CACHE PATH "Path to the dls2_msgs folder" FORCE) +endif() diff --git a/cmake/generate_ros2_messages.cmake b/cmake/generate_ros2_messages.cmake new file mode 100644 index 0000000..7806c7c --- /dev/null +++ b/cmake/generate_ros2_messages.cmake @@ -0,0 +1,46 @@ +# Regenerate ROS2 messages from IDL definitions on every CMake configure. +message(STATUS "Generating ROS2 messages from IDL files...") +set(DLS2_ROS2_INTERFACE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dls2_ros2_interface/ros2_ws/src") +set(DLS2_ROS2_INTERFACE_DIR "${DLS2_ROS2_INTERFACE_SRC_DIR}/dls2_interface") +find_package(Python3 REQUIRED COMPONENTS Interpreter) +file(GLOB DLS_IDL_FILES CONFIGURE_DEPENDS "${DLS_MESSAGE_FOLDER}/idls/*.idl") +if(NOT DLS_IDL_FILES) + message(FATAL_ERROR "No IDL files found in '${DLS_MESSAGE_FOLDER}/idls'. Existing ROS2 messages were preserved.") +endif() +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + ${DLS_IDL_FILES} "${DLS2_ROS2_INTERFACE_DIR}/scripts/idl_to_msg.py") + +# Generate in the build tree first so a conversion failure preserves existing messages. +set(DLS_ROS2_MSG_STAGE "${CMAKE_CURRENT_BINARY_DIR}/generated_ros2_messages") +file(REMOVE_RECURSE "${DLS_ROS2_MSG_STAGE}") +file(MAKE_DIRECTORY "${DLS_ROS2_MSG_STAGE}") +foreach(idl_file IN LISTS DLS_IDL_FILES) + execute_process( + COMMAND "${Python3_EXECUTABLE}" "${DLS2_ROS2_INTERFACE_DIR}/scripts/idl_to_msg.py" + "${idl_file}" --strict -o "${DLS_ROS2_MSG_STAGE}" + WORKING_DIRECTORY "${DLS2_ROS2_INTERFACE_DIR}" + RESULT_VARIABLE DLS_IDL_RESULT + OUTPUT_VARIABLE DLS_IDL_OUTPUT + ERROR_VARIABLE DLS_IDL_ERROR + ) + if(NOT "${DLS_IDL_RESULT}" STREQUAL "0") + message(FATAL_ERROR "ROS2 message generation failed for '${idl_file}':\n${DLS_IDL_OUTPUT}\n${DLS_IDL_ERROR}\nExisting ROS2 messages were preserved.") + endif() +endforeach() + +file(GLOB DLS_GENERATED_MSG_FILES "${DLS_ROS2_MSG_STAGE}/dls2_interface/msg/*.msg") +if(NOT DLS_GENERATED_MSG_FILES) + message(FATAL_ERROR "No dls2_interface messages were generated. Existing ROS2 messages were preserved.") +endif() +file(COPY ${DLS_GENERATED_MSG_FILES} DESTINATION "${DLS2_ROS2_INTERFACE_DIR}/msg") + +# Remove obsolete messages only after all conversions and the copy have succeeded. +file(GLOB DLS_MSG_FILES "${DLS2_ROS2_INTERFACE_DIR}/msg/*.msg") +foreach(msg_file IN LISTS DLS_MSG_FILES) + get_filename_component(msg_name "${msg_file}" NAME) + if(NOT EXISTS "${DLS_ROS2_MSG_STAGE}/dls2_interface/msg/${msg_name}") + file(REMOVE "${msg_file}") + endif() +endforeach() +list(LENGTH DLS_GENERATED_MSG_FILES DLS_GENERATED_MSG_COUNT) +message(STATUS "Generated ${DLS_GENERATED_MSG_COUNT} ROS2 messages in ${DLS2_ROS2_INTERFACE_DIR}/msg") diff --git a/dls2 b/dls2 index 14a776c..8c373a0 160000 --- a/dls2 +++ b/dls2 @@ -1 +1 @@ -Subproject commit 14a776c82e2d2b9a81373cb01d15ecaf906aae5f +Subproject commit 8c373a08c631c25c76c1a17ce661bcadbff5491b diff --git a/dls2_msgs b/dls2_msgs deleted file mode 160000 index c3fe30f..0000000 --- a/dls2_msgs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c3fe30f5df54559da2222dea9261661527e26056 diff --git a/dls2_ros2_interface b/dls2_ros2_interface index 627a2d9..d1364dc 160000 --- a/dls2_ros2_interface +++ b/dls2_ros2_interface @@ -1 +1 @@ -Subproject commit 627a2d952feffa54e51a2bab3789512c75108416 +Subproject commit d1364dc88ac9659c369a894704460cd4da125fbb diff --git a/dls_hal b/dls_hal new file mode 160000 index 0000000..5d432fc --- /dev/null +++ b/dls_hal @@ -0,0 +1 @@ +Subproject commit 5d432fc31e2ff9b07e71e2c44faec84a93da4ae7 diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 9261d35..874e9d1 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -61,7 +61,7 @@ To start interacting with the DLS2 network, you can now launch the console layer At this point you are now ready to start sending commands to the DLS2 network through the console. -You can also customize the set of nodes you want to launch by creating your yaml file. To do that the yaml file has to contain the following structure +You can also customize the set of nodes you want to launch by creating your yaml file. For example you can use the following structure ``` # layers layers: [] @@ -89,7 +89,7 @@ To launch your configuration file, you need to pass its path to the startup comm dls --startup=/startup.yml -The supervisor and the DDS servers are automatically launched when using the startup procedure. +The supervisor and the DDS servers are launched by the startup procedure only when `run_supervisor` and `run_servers`, respectively, are explicitly set to `true` in the YAML file. Both options default to `false`; omitting an option or setting it to `false` skips launching that component. Automatic simulation model loading also requires `load_model: true`; omitting it or setting it to `false` skips model loading. For a list of all available entries, see the [startup configuration reference](../dls2/doc/StartupConfiguration.md). ## Mixed routine To launch the DLS2 network you could also use a mixed approach: load some layers and nodes with the startup routine and others with the manual steps. \ No newline at end of file diff --git a/pinocchio-gluecode b/pinocchio-gluecode index caa8468..7913f26 160000 --- a/pinocchio-gluecode +++ b/pinocchio-gluecode @@ -1 +1 @@ -Subproject commit caa8468b58792fd81191b7fbb1eeb77a2d3ce3d0 +Subproject commit 7913f262a3644fff826ed5b6b3b02c0ca7377594 diff --git a/transport_interfaces b/transport_interfaces new file mode 160000 index 0000000..85fe334 --- /dev/null +++ b/transport_interfaces @@ -0,0 +1 @@ +Subproject commit 85fe334df67d671d1ef17c6c4c35ed50d573a989 diff --git a/visualizers/rviz_interface/src/rviz_interface.cpp b/visualizers/rviz_interface/src/rviz_interface.cpp index 8ce6d20..2590e09 100644 --- a/visualizers/rviz_interface/src/rviz_interface.cpp +++ b/visualizers/rviz_interface/src/rviz_interface.cpp @@ -101,7 +101,7 @@ namespace periodic_app_plugin // Run robot state publisher in a separate shell command, so rviz can // visualize the robot while this plugin publishes joint states and tf. std::string urdf_path = "/usr/include/" + robot_name + - "_description/urdfs/" + robot_name + "_ros.urdf"; + "-description/urdfs/" + robot_name + "_ros.urdf"; const std::string bash_command = ". /usr/bin/dls2/scripts/setup_ros2_for_dls2.bash && " "setsid ros2 run robot_state_publisher robot_state_publisher "