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 Toolsrepository:git clone https://github.com/awslabs/ros2-migration-tools.git -
Download the
LLVM 8.0.0Pre-Built Binariesfor 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.8shared object and thelibclang.sosymlink fromlibfolder of clang to theros2-migration-tools/clangfolder.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
includefolder to theros2-migration-tools/clang/clangfolder.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.pywill need path topackage.xmlwhich can be provided either using environment variableROS1_PACKAGE_PATHor using the--package_xml_pathargument ofros2-migration-tools/ros_upgrader.py -
Build the
ROS1_PackageROS1 package with-DCMAKE_EXPORT_COMPILE_COMMANDS=ONcolcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -
Building the
ROS1_Packagewith-DCMAKE_EXPORT_COMPILE_COMMANDS=ONwill have created acompile_commands.jsonfile insidebuild/ROS1_Packageif the build was successful. This path will be mandatory argument forros2-migration-tools/ros_upgrader.pyscript.
-
cdtoros2-migration-tools. -
run
ros_upgrader.pyscript with following arguments.-cor--compile_db_path(required): this is path to thecompile_commands.jsonfile-por--package_xml_path(optional): this is path to thepackage.xmlfile-mor--mapping_file(optional): this is name of the file to which filled mappings will be written to-for--filter_out_file(optional): this is name of the file to which unfilled tokens will be written to-oor--output_folder(optional): output directory where the ported package will copied-dor--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.jsonor
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 abortwill 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
outputinside theros2-migration-toolsor the output folder will be the folder which you specified with-oor--output_folderargument. 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.jsonfile 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_PackageTYPECAST_OPERATOR: Typecast operator functions defined in theROS1_PackageHEADER_FILE: Included header files in theROS1_PackageMACRO_DEFINITION: Macros used inROS1_PackageNAMESPACE: Namespaces used inROS1_PackageFUNCTION_PARAMETER: Parameters of functions declared inROS1_PackageVARIABLE_TYPE: Variable types used inROS1_Package
-
If the list is not empty, then update the
ros2_namefield 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_namewas modified, will be moved to the file with name provided using--mapping_fileinsideros2-migration-tools/mappingfolder. Default file name ismaster_mappings.json. -
All elements from the list with value for
ros2_nameunchanged, i.e.ros2_name??, will be moved toIRRELEVANT_TOKENSin the file with name provided using--filer_out_fileinsideros2-migration-tools/token_filersfolder. Default file name isfiltered_out_tokens.json. These elements will not appear inNEW_TOKENS_LISTagain. -
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 totrueif the function needsnode(actual var name) as an argumentnode_arg_ind: Index(0-based) of thenodeargument ifnode_arg_reqwas changed totrue
MACRO_DEFINITION:node_arg_req: This field will be insidenode_arg_info. Change it totrueif the function needsnodemember function as an argumentnode_arg_ind: Index(0-based) of thenodeargument ifnode_arg_reqwas changed totruemember_name_if_true: Name of the member function of ROS2 Node class ifnode_arg_reqwas changed totrue
VARIABLE_TYPE:to_shared_ptr: It should be true if thevar_typeis supposed to beshared_ptr,falseotherwiseto_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_namewith 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.