ros2 / ros1_bridge

ROS 2 package that provides bidirectional communication between ROS 1 and ROS 2
Apache License 2.0
452 stars 288 forks source link

rosbridge services for rule based name matching #241

Open athackst opened 4 years ago

athackst commented 4 years ago

Updated rosbridge to handle services with rule-based name matching.

Motivating use: ROS2 has more strict rules on variable name format in services than ROS1, requiring a name change between ROS1 and ROS2 variables.

This PR fixes:

Tested: On the AWS Deepracer using this dockerfile


This change is Reviewable

dirk-thomas commented 4 years ago

The PR seems to undo changes recently merged as part of #234?

(Also please sign off the commits to pass DCO.)

athackst commented 4 years ago

Working on the DCO.

And yes, I tried those changes, but they didn't work for me :woman_shrugging:

athackst commented 4 years ago

DCO complete.

It would probably be good to add a unit test to better test the services. I was able to test it with my bot, but I'm unaware of a ROS package that has service name differences that's already a part of the ROS ecosystem that also has unit tests.

Alternatively we could add one in this package, but that would mean it would need to be compiled with ROS1 and ROS2 (and be different) and this package is already somewhat tricky to setup.

athackst commented 4 years ago

Any other changes requested on this?

dirk-thomas commented 4 years ago

Any other changes requested on this?

My previous comment still applies:

The PR seems to undo changes recently merged as part of #234?

"I tried those changes, but they didn't work for me" isn't a satisfactory answer for reverting it in this PR.

athackst commented 4 years ago

Here's a detailed console output of the current eloquent branch which appears to be incomplete in actually mapping services of different names in a rosbridge.

Output ```bash Step 28/50 : RUN mkdir -p src && cd src && git clone --branch eloquent https://github.com/ros2/ros1_bridge.git && cd ../ && colcon build --merge-install --packages-select ros1_bridge --cmake-force-configure --install-base /opt/ros/eloquent ---> Running in a79e8d132fc2 Cloning into 'ros1_bridge'... Starting >>> ros1_bridge --- stderr: ros1_bridge CMake Warning at /opt/ros/eloquent/share/actionlib_msgs/cmake/actionlib_msgsConfig.cmake:29 (message): Package 'actionlib_msgs' is deprecated (This package will be removed in a future ROS distro, once the ROS 1 bridge supports actions.) Call Stack (most recent call first): CMakeLists.txt:94 (find_package) /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:124:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Request&, ros1_bridge::ServiceFactory::ROS2Request&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::ActiveStateSrvRequest_ >; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::ActiveStateSrv_Request_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:71:6: note: ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Request&, ros1_bridge::ServiceFactory::ROS2Request&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::ActiveStateSrvRequest_ >; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::ActiveStateSrv_Request_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:137:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Response&, ros1_bridge::ServiceFactory::ROS2Response&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::ActiveStateSrvResponse_ >; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::ActiveStateSrv_Response_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:84:6: note: ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Response&, ros1_bridge::ServiceFactory::ROS2Response&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::ActiveStateSrvResponse_ >; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::ActiveStateSrv_Response_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:150:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Request&, ros1_bridge::ServiceFactory::ROS1Request&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::ActiveStateSrv_Request_ >; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::ActiveStateSrvRequest_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:97:6: note: ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Request&, ros1_bridge::ServiceFactory::ROS1Request&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::ActiveStateSrv_Request_ >; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::ActiveStateSrvRequest_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:163:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Response&, ros1_bridge::ServiceFactory::ROS1Response&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::ActiveStateSrv_Response_ >; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::ActiveStateSrvResponse_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp:110:6: note: ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Response&, ros1_bridge::ServiceFactory::ROS1Response&) [with ROS1_T = ctrl_pkg::ActiveStateSrv; ROS2_T = ctrl_pkg::srv::ActiveStateSrv; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::ActiveStateSrv_Response_ >; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::ActiveStateSrvResponse_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::ActiveStateSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::ActiveStateSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ make[2]: *** [CMakeFiles/ros1_bridge.dir/generated/ctrl_pkg__srv__ActiveStateSrv__factories.cpp.o] Error 1 make[2]: *** Waiting for unfinished jobs.... /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:124:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Request&, ros1_bridge::ServiceFactory::ROS2Request&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::NavThrottleSrvRequest_ >; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::NavThrottleSrv_Request_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:71:6: note: ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Request&, ros1_bridge::ServiceFactory::ROS2Request&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::NavThrottleSrvRequest_ >; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::NavThrottleSrv_Request_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:137:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Response&, ros1_bridge::ServiceFactory::ROS2Response&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::NavThrottleSrvResponse_ >; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::NavThrottleSrv_Response_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:84:6: note: ‘void ros1_bridge::ServiceFactory::translate_1_to_2(const ROS1Response&, ros1_bridge::ServiceFactory::ROS2Response&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::NavThrottleSrvResponse_ >; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::NavThrottleSrv_Response_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_1_to_2( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:150:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Request&, ros1_bridge::ServiceFactory::ROS1Request&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::NavThrottleSrv_Request_ >; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::NavThrottleSrvRequest_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:97:6: note: ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Request&, ros1_bridge::ServiceFactory::ROS1Request&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS2Request = ctrl_pkg::srv::NavThrottleSrv_Request_ >; ros1_bridge::ServiceFactory::ROS1Request = ctrl_pkg::NavThrottleSrvRequest_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:163:6: error: redefinition of ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Response&, ros1_bridge::ServiceFactory::ROS1Response&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::NavThrottleSrv_Response_ >; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::NavThrottleSrvResponse_ >]’ void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ /workspaces/ros1_bridge/build/ros1_bridge/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp:110:6: note: ‘void ros1_bridge::ServiceFactory::translate_2_to_1(const ROS2Response&, ros1_bridge::ServiceFactory::ROS1Response&) [with ROS1_T = ctrl_pkg::NavThrottleSrv; ROS2_T = ctrl_pkg::srv::NavThrottleSrv; ros1_bridge::ServiceFactory::ROS2Response = ctrl_pkg::srv::NavThrottleSrv_Response_ >; ros1_bridge::ServiceFactory::ROS1Response = ctrl_pkg::NavThrottleSrvResponse_ >]’ previously declared here void ServiceFactory< ^~~~~~~~~~~~~~~ ctrl_pkg::NavThrottleSrv, ~~~~~~~~~~~~~~~~~~~~~~~~~ ctrl_pkg::srv::NavThrottleSrv ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >::translate_2_to_1( ~ make[2]: *** [CMakeFiles/ros1_bridge.dir/generated/ctrl_pkg__srv__NavThrottleSrv__factories.cpp.o] Error 1 make[1]: *** [CMakeFiles/ros1_bridge.dir/all] Error 2 make: *** [all] Error 2 --- Failed <<< ros1_bridge [ Exited with code 2 ] [Processing: ros1_bridge] Summary: 0 packages finished [42.3s] 1 package failed: ros1_bridge 1 package had stderr output: ros1_bridge ```

And a corresponding dockerfile to reproduce:

Dockerfile ```docker # Dockerfile to bridge the ros1 and ros2 messages # # Build the ros1 messages # ------------------------ FROM athackst/ros:melodic-dev as ros_builder WORKDIR /workspaces/ros RUN mkdir -p src && cd src \ && git clone --branch kinetic https://github.com/athackst/aws_deepracer_msgs.git \ && cd ../ \ && catkin_make install -DCMAKE_INSTALL_PREFIX=/opt/ros/melodic # # Build the ros2 messages # ------------------------ FROM athackst/ros2:eloquent-dev as ros2_builder WORKDIR /workspaces/ros2 RUN mkdir -p src && cd src \ && git clone --branch eloquent https://github.com/athackst/aws_deepracer_msgs.git \ && cd ../ \ && colcon build --merge-install --install-base /opt/ros/eloquent # # Build the ros1_bridge # ----------------------- FROM athackst/ros2:eloquent-dev as ros1_bridge_builder # install melodic RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' \ && apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 \ && apt-get update \ && apt-get install -y ros-melodic-ros-base \ && rm -rf /var/lib/apt/lists/* # Get the ros messages COPY --from=ros_builder /opt/ros/melodic /opt/ros/melodic # Get the ros2 messages COPY --from=ros2_builder /opt/ros/eloquent/ /opt/ros/eloquent # Deps for the bridge RUN apt-get update && apt-get install -y \ # Test deps ros-eloquent-demo-nodes-cpp \ ros-eloquent-launch-testing \ ros-eloquent-launch-testing-ament-cmake \ ros-eloquent-launch-testing-ros \ ros-melodic-rospy-tutorials \ ros-melodic-roscpp-tutorials \ # Build deps libboost-filesystem-dev \ libboost-math-dev \ libboost-regex-dev \ libboost-signals-dev \ libboost-thread-dev \ liblog4cxx-dev \ && rm -rf /var/lib/apt/lists/* # Set up the environment ENV LD_LIBRARY_PATH=/opt/ros/eloquent/lib:/opt/ros/melodic/lib ENV AMENT_PREFIX_PATH=/opt/ros/eloquent ENV ROS_ETC_DIR=/opt/ros/melodic/etc/ros ENV COLCON_PREFIX_PATH=/opt/ros/eloquent ENV ROS_ROOT=/opt/ros/melodic/share/ros ENV ROS_MASTER_URI=http://localhost:11311 ENV ROS_VERSION=2 ENV ROS_LOCALHOST_ONLY=0 ENV ROS_PYTHON_VERSION=3 ENV PYTHONPATH=/opt/ros/eloquent/lib/python3.6/site-packages:/opt/ros/melodic/lib/python2.7/dist-packages ENV ROS_PACKAGE_PATH=/opt/ros/melodic/share ENV ROSLISP_PACKAGE_DIRECTORIES= ENV PATH=/opt/ros/eloquent/bin:/opt/ros/melodic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ENV PKG_CONFIG_PATH=/opt/ros/melodic/lib/pkgconfig ENV CMAKE_PREFIX_PATH=/opt/ros/eloquent:/opt/ros/melodic # Build the bridge WORKDIR /workspaces/ros1_bridge RUN mkdir -p src && cd src \ && git clone --branch eloquent https://github.com/ros2/ros1_bridge.git \ && cd ../ \ && colcon build --merge-install --packages-select ros1_bridge --cmake-force-configure --install-base /opt/ros/eloquent ```
athackst commented 4 years ago

To be fair, my intention isn't to "revert a PR" -- it's to make service mapping work.

I have now provided an example of the output I was seeing with the current state of the code, as well as a dockerfile for you to reproduce it on your end. I don't believe I'm doing something wrong in my set up. If I have, please let me know what I did wrong?

I was able to successfully map services after I made changes to the code base, which I'm sharing here, since I thought it might be valuable to others.

athackst commented 4 years ago

Ping @nuclearsandwich.

Any update on this?