Translating your applications

You can use the Automatic code generation with rpk tool to create a new node skeleton that supports internationalisation.

Go to your workspace’s src/ directory and run:

$ rpk create -r generic mission

Then, select your desired name (e.g. internationalised_app) and then choose the template number 2 (robot supervisor with pre-filled intent handlers).

The main aspects that have been done with respect to internationalisation are:

  • The node installs in i18n.localized_nodes from ament_index a marker file containing the fully qualified name of the node to be managed. This is to let the i18n_manager know that this node supports internationalisation.

  • The node must implement the i18n_msgs/srv/GetLocales service, which will be used to get the list of supported locales by the node. If this service is not implemented, the node will be ignored by the i18n_manager.

  • The node must implement the i18n_msgs/action/SetLocale action, which will be used to change the node’s locale.

  • The node must provide a default_locale parameter, which is initialised with the default locale of the node and is changed when the i18n_msgs/action/SetLocale action is called.

Although we recommend using rpk to generate the code of an internationalised application, or at lest to get inspired from, you can also manually modify your existing nodes to support internationalisation.

Here is an example in python of a node that supports internationalisation:

from rclpy.node import Node
from rclpy.action import ActionServer, GoalResponse
from i18n_msgs.action import SetLocale
from i18n_msgs.srv import GetLocales
from rclpy.parameter import Parameter
from rcl_interfaces.msg import ParameterDescriptor

class MyInternationalizedNode(Node):
    def __init__(self):
        super().__init__('my_internationalized_node')
        self.available_locales = ['en_US', 'fr_FR']  # Example locales
        self.set_default_locale_server = ActionServer(
            self, SetLocale, "~/set_default_locale",
            goal_callback=self.on_set_default_locale_goal,
            execute_callback=self.on_set_default_locale_exec)
        self.get_supported_locales_service = self.create_service(
            GetLocales, "~/get_supported_locales",
            self.on_get_supported_locales))
        self.declare_parameter(
            'default_locale', 'en_US',
            ParameterDescriptor(description='Default locale'))

    def on_get_supported_locales(self, request, response):
        response.locales = self.available_locales
        return response

    def on_set_default_locale_goal(self, goal_request):
        if goal_request.locale in self.available_locales:
            return GoalResponse.ACCEPT
        else:
            return GoalResponse.REJECT

    def on_set_default_locale_exec(self, goal_handle):
        locale = goal_handle.request.locale
        result = SetLocale.Result()
        locale_changed = True # Assume we can change the locale
        if locale_changed:
            self.set_parameters([Parameter('default_locale', value=locale)])
            goal_handle.succeed()
        else:
            goal_handle.abort()
        return result

Then, create a marker file in the package with the name of the node, e.g. internationalised_app where its content is /internationalised_app, and in setup.py, you can add the resource to ament_index:

setup(
    ...
    data_files=[
        ('share/ament_index/resource_index/i18n/localized_nodes', ['YOUR_RESOURCE_FILE_PATH']),
    ],
    ...
)

See also