This repo contains a set of tools for migrating a ROS1 package to a ROS2 package.
The C++ source code migration uses libclang8 and its corresponding python bindings.
The main script for migration is ros_upgrader.py
This set of tools supports the migration of CMakeLists.txt
and package.xml
files.
This set of tools supports the migration of C++ source codes.
This set of tools does not handle any changes to message or service declarations.
This set of tools currently does not support migrating ROS1 launch files to ROS2 launch files.
- ROS1 system
- Python-3.5 or higher
- parse-cmake: Install using
pip3 install parse_cmake
-
On the ROS1 system, clone the
ROS2 Migration Tools
repository:git clone https://github.com/awslabs/ros2-migration-tools.git
-
Download the
LLVM 8.0.0
Pre-Built Binaries
for your version of Linux from llvm download page. For example, download Ubuntu 16.04 (.sig) if your machine is running Ubuntu 16.06. -
Extract the downloaded tarball (for example,
tar xvf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
). -
Copy the
libclang.so.8
shared object and thelibclang.so
symlink fromlib
folder of clang to theros2-migration-tools/clang
folder.cp -r <extracted directory>/lib/libclang.so <ros2-migration-tools directory>/clang cp -r <extracted directory>/lib/libclang.so.8 <ros2-migration-tools directory>/clang
-
Copy the contents of the libclang
include
folder to theros2-migration-tools/clang/clang
folder.cp -r <extracted directory>/lib/clang/8.0.0/include <ros2-migration-tools directory>/clang/clang
-
Clone the sources of the ROS1 package which you want to port. Lets say the package cloned is named
ROS1_Package
.ros2-migration-tools/ros_upgrader.py
will need path topackage.xml
which can be provided either using environment variableROS1_PACKAGE_PATH
or using the--package_xml_path
argument ofros2-migration-tools/ros_upgrader.py
-
Build the
ROS1_Package
ROS1 package with-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-
Building the
ROS1_Package
with-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
will have created acompile_commands.json
file insidebuild/ROS1_Package
if the build was successful. This path will be mandatory argument forros2-migration-tools/ros_upgrader.py
script.
-
cd
toros2-migration-tools
. -
run
ros_upgrader.py
script with following arguments.-c
or--compile_db_path
(required): this is path to thecompile_commands.json
file-p
or--package_xml_path
(optional): this is path to thepackage.xml
file-m
or--mapping_file
(optional): this is name of the file to which filled mappings will be written to-f
or--filter_out_file
(optional): this is name of the file to which unfilled tokens will be written to-o
or--output_folder
(optional): output directory where the ported package will copied-d
or--debug
(optional): add this flag if you want to dump the Abstract Syntax Tree created
For example,
export ROS1_PACKAGE_PATH=ROS1_Package/package.xml ros_upgrader.py -c ROS1_Package/build/ROS1_Package/compile_commands.json
or
ros_upgrader.py -c ROS1_Package/build/ROS1_Package/compile_commands.json -p ROS1_Package/package.xml
Note: Paths can also be relative to the ros_upgrader.py
package. ROS1_Package/package.xml
must be provided by one of the two ways explained.
-
One of the following can happen now:
- If there are no new tokens encountered in the ROS1 package, then it will just finish running
- If there are some new tokens encountered, there will be message on terminal saying
Open mapping/new_tokens.json and fill the mappings. Press 'Y' to continue or any other key to abort
will be shown on terminal. Don't press 'Y' yet. See the Filling the mappings section on for more details about the mappings
-
Default output folder is a folder named
output
inside theros2-migration-tools
or the output folder will be the folder which you specified with-o
or--output_folder
argument. The default folder will have a folder with unique namecurrData_currTime
(e.g.2019-07-15_20_30_55
). This output folder will contain the package migrated to ROS2
-
Open
mapping/new_tokens.json
file in editor of choice. -
Each key in the file contains a list. Following are the keys:
FUNCTION_CALL
: Function calls and constructor calls used inROS1_Package
TYPECAST_OPERATOR
: Typecast operator functions defined in theROS1_Package
HEADER_FILE
: Included header files in theROS1_Package
MACRO_DEFINITION
: Macros used inROS1_Package
NAMESPACE
: Namespaces used inROS1_Package
FUNCTION_PARAMETER
: Parameters of functions declared inROS1_Package
VARIABLE_TYPE
: Variable types used inROS1_Package
-
If the list is not empty, then update the
ros2_name
field for each of of the objects in the list. These can be left unchanged if no change is required for them in ROS2 -
All the elements from the list whose value for
ros2_name
was modified, will be moved to the file with name provided using--mapping_file
insideros2-migration-tools/mapping
folder. Default file name ismaster_mappings.json
. -
All elements from the list with value for
ros2_name
unchanged, i.e.ros2_name??
, will be moved toIRRELEVANT_TOKENS
in the file with name provided using--filer_out_file
insideros2-migration-tools/token_filers
folder. Default file name isfiltered_out_tokens.json
. These elements will not appear inNEW_TOKENS_LIST
again. -
Some key categories will also require some additional information which is explained below:
FUNCTION_CALL
:node_arg_req
: This field will be insidenode_arg_info
. Change it totrue
if the function needsnode
(actual var name) as an argumentnode_arg_ind
: Index(0-based) of thenode
argument ifnode_arg_req
was changed totrue
MACRO_DEFINITION
:node_arg_req
: This field will be insidenode_arg_info
. Change it totrue
if the function needsnode
member function as an argumentnode_arg_ind
: Index(0-based) of thenode
argument ifnode_arg_req
was changed totrue
member_name_if_true
: Name of the member function of ROS2 Node class ifnode_arg_req
was changed totrue
VARIABLE_TYPE
:to_shared_ptr
: It should be true if thevar_type
is supposed to beshared_ptr
,false
otherwiseto_be_removed
: It should be true if any var type needs to be removed
FUNCTION_PARAMETER
: It may contain&
or*
, e.g,ros::NodeHandle &
. Provideros2_name
with exactly what you want to replace it with
Note: If there is no change in name from ROS1 to ROS2 but above fields like node_arg_req
is changed, then change
the field ros2_name
same as ros1_name
, i.e. do change it from ros2_name??
otherwise it will get added to the
IRRELEVANT_TOKENS
Note: If there is scope resolution included in ros1_name
(e.g. ros::ros1_token
), then only change the
ros1_token
to corresponding ros2_token
. So ros2_name
field would look like ros::ros2_token
and not like rclcpp::ros2_token
.
Namespace change will be taken care by NAMESPACE
category.