Skip to content

Commit 2b1789f

Browse files
Enable ros2service call to accept YAML input without escaping special characters
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
1 parent 3b7efa1 commit 2b1789f

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

ros2service/ros2service/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,5 @@ def __init__(self, *, service_type_key=None):
140140

141141
def __call__(self, prefix, parsed_args, **kwargs):
142142
service = get_service(getattr(parsed_args, self.service_type_key))
143-
return [message_to_yaml(service.Request())]
143+
yaml_snippet = "'" + message_to_yaml(service.Request()) + "'"
144+
return [yaml_snippet]

ros2service/ros2service/verb/call.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
import time
1616
from typing import Optional
1717

18+
import argcomplete
19+
1820
import rclpy
1921
from rclpy.qos import QoSPresetProfiles
2022
from rclpy.qos import QoSProfile
2123

22-
from ros2cli.helpers import collect_stdin
24+
from ros2cli.helpers import collect_stdin, UnescapedCompletionFinder
2325
from ros2cli.helpers import interactive_select
2426
from ros2cli.node import NODE_NAME_PREFIX
2527
from ros2cli.node.strategy import NodeStrategy
@@ -67,6 +69,10 @@ def add_arguments(self, parser, cli_name):
6769
parser.add_argument(
6870
'-r', '--rate', metavar='N', type=float,
6971
help='Repeat the call at a specific rate in Hz')
72+
73+
# Prevent argcomplete from escaping special characters in the YAML string
74+
argcomplete.autocomplete = UnescapedCompletionFinder(parser)
75+
7076
add_qos_arguments(parser, 'service client', 'services_default')
7177

7278
def main(self, *, args):
@@ -117,7 +123,16 @@ def requester(service_type: str, service_name: str, values, period: Optional[flo
117123
except (AttributeError, ModuleNotFoundError):
118124
raise RuntimeError('The passed service type is invalid')
119125

120-
values_dictionary = yaml.safe_load(values)
126+
try:
127+
# Handle cases where the user pastes the autocompleted bash safe string
128+
if '^J' in values:
129+
values = values.replace("'", '')
130+
values = values.replace('^J', '\n')
131+
132+
values_dictionary = yaml.safe_load(values)
133+
134+
except (yaml.parser.ParserError, yaml.scanner.ScannerError):
135+
return 'The passed value needs to be in YAML string or a dictionary'
121136

122137
with rclpy.init():
123138
node = rclpy.create_node(NODE_NAME_PREFIX + '_requester_%s_%s' % (package_name, srv_name))

0 commit comments

Comments
 (0)