Skip to content

Commit 219fff7

Browse files
committed
Initial release to open source
1 parent fcb19f9 commit 219fff7

15 files changed

+552
-1
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
# ros1_tools
1+
# ros1_tools
2+
3+
## ros1_message_mirror
4+
5+
Provides the `rosidl_from_ros1_package` cmake macro, allowing one to easily clone message definitions from ROS1 into ROS2

json_msgs/CMakeLists.txt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(json_msgs)
3+
4+
if(NOT CMAKE_CXX_STANDARD)
5+
set(CMAKE_CXX_STANDARD 14)
6+
endif()
7+
8+
find_package(ament_cmake REQUIRED)
9+
find_package(ros1_message_mirror REQUIRED)
10+
11+
rosidl_from_ros1_package(
12+
${PROJECT_NAME}
13+
)
14+
15+
if(BUILD_TESTING)
16+
find_package(ament_lint_auto REQUIRED)
17+
18+
# Ignore copyright linting, for now
19+
set(ament_cmake_copyright_FOUND TRUE)
20+
ament_lint_auto_find_test_dependencies()
21+
endif()
22+
23+
ament_package()

json_msgs/package.xml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
5+
<name>json_msgs</name>
6+
<version>0.4.0</version>
7+
<description>locus_msgs port to ROS2</description>
8+
9+
<maintainer email="[email protected]">Paul Bovbel</maintainer>
10+
<license>Apache License 2.0</license>
11+
<author email="[email protected]">Paul Bovbel</author>
12+
13+
<buildtool_depend>ament_cmake</buildtool_depend>
14+
<buildtool_depend>rosidl_default_generators</buildtool_depend>
15+
16+
<depend>ros1_message_mirror</depend>
17+
18+
<test_depend>ament_lint_auto</test_depend>
19+
<test_depend>ament_lint_common</test_depend>
20+
21+
<member_of_group>rosidl_interface_packages</member_of_group>
22+
23+
<export>
24+
<build_type>ament_cmake</build_type>
25+
</export>
26+
27+
</package>

ros1_message_mirror/CMakeLists.txt

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(ros1_message_mirror)
3+
4+
if(NOT WIN32)
5+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Werror")
6+
endif()
7+
8+
find_package(ament_cmake REQUIRED)
9+
10+
ament_python_install_package(${PROJECT_NAME})
11+
12+
install(
13+
DIRECTORY cmake
14+
DESTINATION share/${PROJECT_NAME}
15+
)
16+
17+
install(
18+
PROGRAMS
19+
scripts/adapt_ros1_message
20+
scripts/get_ros1_messages
21+
DESTINATION lib/${PROJECT_NAME}
22+
)
23+
24+
if(BUILD_TESTING)
25+
find_package(ament_lint_auto REQUIRED)
26+
27+
# Ignore copyright linting, for now
28+
set(ament_cmake_copyright_FOUND TRUE)
29+
ament_lint_auto_find_test_dependencies()
30+
endif()
31+
32+
ament_package(
33+
CONFIG_EXTRAS ros1_message_mirror-extras.cmake
34+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright 2015 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
macro(find_ros1_package name)
16+
cmake_parse_arguments(_ARG "REQUIRED" "" "" ${ARGN})
17+
if(_ARG_UNPARSED_ARGUMENTS)
18+
message(FATAL_ERROR
19+
"find_ros1_package() called with unused arguments: "
20+
"${ARG_UNPARSED_ARGUMENTS}")
21+
endif()
22+
23+
find_package(PkgConfig REQUIRED)
24+
# the error message of pkg_check_modules for not found required modules
25+
# doesn't include the module name which is not helpful
26+
pkg_check_modules(ros1_${name} ${name})
27+
if(NOT ros1_${name}_FOUND)
28+
if(_ARG_REQUIRED)
29+
message(FATAL_ERROR
30+
"find_ros1_package() failed to find '${name}' using "
31+
"pkg_check_modules()")
32+
endif()
33+
else()
34+
set(_libraries "${ros1_${name}_LIBRARIES}")
35+
# Prior to catkin 0.7.7, dependent libraries in the pkg-config file were always generated
36+
# in the form "-l:/absolute/path/to/library". Because of the leading "-l", this made
37+
# them show up in ${ros1_${name}_LIBRARIES}. catkin 0.7.7 and later has changed this to
38+
# just be an absolute path (of the form "/absolute/path/to/library"), so we now have to
39+
# look through the LDFLAGS_OTHER and add those to the libraries that we need to link with.
40+
foreach(_flag ${ros1_${name}_LDFLAGS_OTHER})
41+
if(IS_ABSOLUTE ${_flag})
42+
list(APPEND _libraries "${_flag}")
43+
endif()
44+
endforeach()
45+
set(_library_dirs "${ros1_${name}_LIBRARY_DIRS}")
46+
set(ros1_${name}_LIBRARIES "")
47+
set(ros1_${name}_LIBRARY_DIRS "")
48+
foreach(_library ${_libraries})
49+
string(SUBSTRING "${_library}" 0 1 _prefix)
50+
if("${_prefix} " STREQUAL ": ")
51+
string(SUBSTRING "${_library}" 1 -1 _rest)
52+
list(APPEND ros1_${name}_LIBRARIES ${_rest})
53+
elseif(IS_ABSOLUTE ${_library})
54+
list(APPEND ros1_${name}_LIBRARIES ${_library})
55+
else()
56+
set(_lib "${_library}-NOTFOUND")
57+
set(_lib_path "")
58+
# since the path where the library is found is not returned
59+
# this has to be done for each path separately
60+
foreach(_path ${_library_dirs})
61+
find_library(_lib ${_library}
62+
PATHS ${_path}
63+
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
64+
if(_lib)
65+
set(_lib_path ${_path})
66+
break()
67+
endif()
68+
endforeach()
69+
if(_lib)
70+
list(APPEND ros1_${name}_LIBRARIES ${_lib})
71+
list_append_unique(ros1_${name}_LIBRARY_DIRS ${_lib_path})
72+
else()
73+
# as a fall back try to search globally
74+
find_library(_lib ${_library})
75+
if(NOT _lib)
76+
message(FATAL_ERROR "pkg-config module '${name}' failed to find library '${_library}'")
77+
endif()
78+
list(APPEND ros1_${name}_LIBRARIES ${_lib})
79+
endif()
80+
endif()
81+
endforeach()
82+
endif()
83+
endmacro()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
macro(rosidl_from_ros1_package package)
2+
3+
cmake_parse_arguments(args "" "" "DEPENDENCIES;ENTITIES" ${ARGN})
4+
5+
find_package(rosidl_default_generators REQUIRED)
6+
find_package(builtin_interfaces REQUIRED)
7+
8+
foreach(dependency ${args_DEPENDENCIES})
9+
find_package(${dependency})
10+
endforeach()
11+
12+
# TODO(pbovbel) register bin path
13+
set(bin_path ${CMAKE_INSTALL_PREFIX}/lib/ros1_message_mirror)
14+
15+
set(message_types "msg" "srv")
16+
17+
foreach(message_type ${message_types})
18+
execute_process(COMMAND ${bin_path}/get_ros1_messages ${package} --type ${message_type}
19+
OUTPUT_VARIABLE ${message_type}_ROS1_LIST
20+
OUTPUT_STRIP_TRAILING_WHITESPACE
21+
)
22+
23+
set(${message_type}_ROS2_LIST "")
24+
25+
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/${message_type}/")
26+
27+
foreach(input_message ${${message_type}_ROS1_LIST})
28+
stamp(${input_message}) # Reconfigure if the upstream message file changes
29+
get_filename_component(filename ${input_message} NAME)
30+
31+
if(args_ENTITIES AND NOT filename IN_LIST args_ENTITIES)
32+
continue()
33+
endif()
34+
35+
execute_process(
36+
COMMAND ${bin_path}/adapt_ros1_message ${input_message} ${CMAKE_BINARY_DIR}/${message_type}/${filename}
37+
OUTPUT_VARIABLE output_message
38+
OUTPUT_STRIP_TRAILING_WHITESPACE
39+
)
40+
41+
# TODO(pbovbel) automatically generate mapping_rules.yaml
42+
list(APPEND ${message_type}_ROS2_LIST ${output_message})
43+
44+
endforeach()
45+
endforeach()
46+
47+
# How does rosidl know if something's a srv or msg? By the file extension?
48+
# No! by the containing directory! *facepalm*
49+
# https://github.com/ros2/rosidl/issues/213
50+
if(msg_ROS2_LIST OR srv_ROS2_LIST)
51+
rosidl_generate_interfaces(${package}
52+
${msg_ROS2_LIST}
53+
${srv_ROS2_LIST}
54+
DEPENDENCIES ${args_DEPENDENCIES} builtin_interfaces
55+
ADD_LINTER_TESTS
56+
)
57+
else()
58+
message(FATAL_ERROR "No interface files imported from ROS1 package ${package}")
59+
endif()
60+
61+
ament_export_dependencies(rosidl_default_runtime)
62+
endmacro()

ros1_message_mirror/package.xml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>ros1_message_mirror</name>
5+
<version>0.4.0</version>
6+
<description>Common tools for working with ROS1 components.</description>
7+
8+
<maintainer email="[email protected]">Paul Bovbel</maintainer>
9+
<license>Apache License 2.0</license>
10+
<author email="[email protected]">Paul Bovbel</author>
11+
12+
<buildtool_depend>ament_cmake</buildtool_depend>
13+
<buildtool_depend>rosidl_default_generators</buildtool_depend>
14+
15+
<depend>builtin_interfaces</depend>
16+
17+
<!-- catkin dependencies -->
18+
<!-- <build_export_depend>rosmsg</build_export_depend> -->
19+
20+
<exec_depend>rosidl_default_runtime</exec_depend>
21+
22+
<test_depend>ament_lint_auto</test_depend>
23+
<test_depend>ament_lint_common</test_depend>
24+
25+
<export>
26+
<build_type>ament_cmake</build_type>
27+
</export>
28+
29+
</package>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include("${CMAKE_CURRENT_LIST_DIR}/find_ros1_package.cmake")
2+
include("${CMAKE_CURRENT_LIST_DIR}/rosidl_from_ros1_package.cmake")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2015-2016 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
import os
17+
import sys
18+
19+
# import rospkg which is required by rosmsg
20+
# and likely only available for Python 2
21+
try:
22+
import rospkg
23+
except ImportError:
24+
from importlib.machinery import SourceFileLoader
25+
import subprocess
26+
for python_executable in ['python2', 'python2.7']:
27+
try:
28+
rospkg_path = subprocess.check_output(
29+
[python_executable, '-c', 'import rospkg; print(rospkg.__file__)'])
30+
except (subprocess.CalledProcessError, FileNotFoundError):
31+
continue
32+
rospkg_path = rospkg_path.decode().strip()
33+
if rospkg_path.endswith('.pyc'):
34+
rospkg_path = rospkg_path[:-1]
35+
rospkg = SourceFileLoader('rospkg', rospkg_path).load_module()
36+
if not rospkg:
37+
raise
38+
39+
# more ROS 1 imports
40+
# since ROS 2 should be sourced after ROS 1 it will overlay
41+
# e.g. the message packages, to prevent that from happening (and ROS 1 code to
42+
# fail) ROS 1 paths are moved to the front of the search path
43+
rpp = os.environ.get('ROS_PACKAGE_PATH', '').split(os.pathsep)
44+
for package_path in reversed([p for p in rpp if p]):
45+
if not package_path.endswith(os.sep + 'share'):
46+
continue
47+
ros1_basepath = os.path.dirname(package_path)
48+
for sys_path in sys.path:
49+
if sys_path.startswith(os.path.join(ros1_basepath, '')):
50+
sys.path.remove(sys_path)
51+
sys.path.insert(0, sys_path)
52+
import rosmsg # noqa
53+
54+
55+
56+
extension_to_rosmsg_mode = {
57+
'msg': rosmsg.MODE_MSG,
58+
'srv': rosmsg.MODE_SRV,
59+
}
60+
61+
62+
def get_ros1_message_paths(package, extension):
63+
rospack = rospkg.RosPack()
64+
mode = extension_to_rosmsg_mode[extension]
65+
path = os.path.join(rospack.get_path(package), extension)
66+
msgs = rosmsg.list_types(package, mode, rospack)
67+
return [os.path.join(path, msg.split('/')[-1] + '.' + extension) for msg in msgs]

0 commit comments

Comments
 (0)