From 9030befec2d5fe527fa8af1bf5c2b52c9448a720 Mon Sep 17 00:00:00 2001 From: Vinman Date: Wed, 8 Dec 2021 14:18:12 +0800 Subject: [PATCH] add xarm_user_params.yaml - Default configuration: xarm_api/config/xarm_params.yaml - Custom configuration: xarm_api/config/xarm_user_params.yaml - When reading the configuration, the custom configuration will overwrite the content of the same field in the default configuration --- .gitignore | 3 ++- ReadMe.md | 2 +- ReadMe_cn.md | 2 +- xarm_api/config/xarm_params.yaml | 2 ++ xarm_api/launch/_xarm_driver.launch.py | 36 +++++++++++++++++++++----- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 08a74569..103a3bea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode/ .idea/ *bak/ -ignore_* \ No newline at end of file +ignore_* +xarm_api/config/xarm_user_params.yaml \ No newline at end of file diff --git a/ReadMe.md b/ReadMe.md index 20d24373..e9672e0e 100755 --- a/ReadMe.md +++ b/ReadMe.md @@ -98,7 +98,7 @@ __Reminder 3: All following instructions will base on xArm6,please use prope - ### 5.4 xarm_api This package is a ros wrapper of "xarm_sdk",functions are implemented as ros service or ros topic,communications with real xArm in "xarm_ros2" are based on the services and topics provided in this part. All the services and topics are under xarm/ namespace by default(unless 'hw_ns' parameter is specified),e.g. full name for "joint_states" is actually "xarm/joint_states". - - __services__: the name of provided services are the same with the corresponding function in SDK, however, whether to activate the service is up to the configuration under the "services" domain in ```xarm_api/config/xarm_params.yaml```. The defined service can only be activated at initialization if that service is configured to ```true```. + - __services__: the name of provided services are the same with the corresponding function in SDK, however, whether to activate the service is up to the configuration under the "services" domain in ```xarm_api/config/xarm_params.yaml``` and ```xarm_api/config/xarm_user_params.yaml```. The defined service can only be activated at initialization if that service is configured to ```true```. If you need to customize the parameters, please create a file ```xarm_api/config/xarm_user_params.yaml``` to modify, the format, refer to ```xarm_api/config/xarm_params.yaml```. ``` services: motion_enable: true diff --git a/ReadMe_cn.md b/ReadMe_cn.md index 4ac5bdbf..412d8be6 100755 --- a/ReadMe_cn.md +++ b/ReadMe_cn.md @@ -95,7 +95,7 @@ __注意3: 以下启动说明以6轴为例,5轴和7轴的用法只需找到 此模块是针对xarm_sdk封装,提供对应的ros service和ros topic,整个xarm_ros2是通过使用此模块的service和topic来和机械臂的通信的 所有service和topic默认都处于xarm/空间下(除非指定了hw_ns参数),即joint_states的完整名字为xarm/joint_states - - __services__: 所有提供的service的名字和SDK中的API名字是对应的,但是否创建对应的服务是根据```xarm_api/config/xarm_params.yaml```的services来决定的,只有当services下对应的service的值为```true```时才会创建对应的service。 + - __services__: 所有提供的service的名字和SDK中的API名字是对应的,但是否创建对应的服务是根据```xarm_api/config/xarm_params.yaml```和```xarm_api/config/xarm_user_params.yaml```的services来决定的,只有当services下对应的service的值为```true```时才会创建对应的service,如果需要自定义参数,请创建```xarm_api/config/xarm_user_params.yaml```文件来修改,格式参照```xarm_api/config/xarm_params.yaml```。 ``` services: diff --git a/xarm_api/config/xarm_params.yaml b/xarm_api/config/xarm_params.yaml index ea4c170d..b4d2bd91 100644 --- a/xarm_api/config/xarm_params.yaml +++ b/xarm_api/config/xarm_params.yaml @@ -1,3 +1,5 @@ +# Please do not modify this file, this configuration is the default configuration +# if you need to modify, please modify xarm_user_params.yaml xarm_driver: ros__parameters: DOF: 7 diff --git a/xarm_api/launch/_xarm_driver.launch.py b/xarm_api/launch/_xarm_driver.launch.py index 25927eec..89b2e195 100644 --- a/xarm_api/launch/_xarm_driver.launch.py +++ b/xarm_api/launch/_xarm_driver.launch.py @@ -16,17 +16,38 @@ from launch_ros.actions import Node -def generate_xarm_params(xarm_params_path, ros_namespace=''): - if ros_namespace: - with open(xarm_params_path, 'r') as f: +def merge_dict(dict1, dict2): + for k, v in dict1.items(): + try: + if k not in dict2: + continue + if isinstance(v, dict): + merge_dict(v, dict2[k]) + else: + dict1[k] = dict2[k] + except Exception as e: + pass + + +def generate_xarm_params(xarm_default_params_path, xarm_user_params_path=None, ros_namespace=''): + if not os.path.exists(xarm_user_params_path): + xarm_user_params_path = None + if ros_namespace or (xarm_user_params_path is not None and xarm_default_params_path != xarm_user_params_path): + with open(xarm_default_params_path, 'r') as f: ros2_control_params_yaml = yaml.safe_load(f) - xarm_params_yaml = { - ros_namespace: ros2_control_params_yaml - } + with open(xarm_user_params_path, 'r') as f: + ros2_control_user_params_yaml = yaml.safe_load(f) + merge_dict(ros2_control_params_yaml, ros2_control_user_params_yaml) + if ros_namespace: + xarm_params_yaml = { + ros_namespace: ros2_control_params_yaml + } + else: + xarm_params_yaml = ros2_control_params_yaml with NamedTemporaryFile(mode='w', prefix='launch_params_', delete=False) as h: yaml.dump(xarm_params_yaml, h, default_flow_style=False) return h.name - return xarm_params_path + return xarm_default_params_path def launch_setup(context, *args, **kwargs): @@ -70,6 +91,7 @@ def launch_setup(context, *args, **kwargs): xarm_params = generate_xarm_params( os.path.join(get_package_share_directory('xarm_api'), 'config', 'xarm_params.yaml'), + os.path.join(get_package_share_directory('xarm_api'), 'config', 'xarm_user_params.yaml'), LaunchConfiguration('ros_namespace', default='').perform(context) )