rosros 0.2.5
Simple unified interface to ROS1 / ROS2 Python API
Loading...
Searching...
No Matches
node.py
Go to the documentation of this file.
1"""
2Partial stand-in of ROS2 `rclpy.node` for ROS1.
3
4Heavily modified copy from ROS2 `rclpy.node`,
5at https://github.com/ros2/rclpy (`rclpy/rclpy/node.py`),
6released under the Apache 2.0 License.
7
8------------------------------------------------------------------------------
9This file is part of rosros - simple unified interface to ROS1 / ROS2.
10Released under the BSD License.
11
12@author Erki Suurjaak
13@created 14.02.2022
14@modified 25.06.2022
15------------------------------------------------------------------------------
16"""
17## @namespace rosros.rclify.node
18
19# Original file copyright notice:
20#
21# Copyright 2016 Open Source Robotics Foundation, Inc.
22#
23# Licensed under the Apache License, Version 2.0 (the "License");
24# you may not use this file except in compliance with the License.
25# You may obtain a copy of the License at
26#
27# http://www.apache.org/licenses/LICENSE-2.0
28#
29# Unless required by applicable law or agreed to in writing, software
30# distributed under the License is distributed on an "AS IS" BASIS,
31# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32# See the License for the specific language governing permissions and
33# limitations under the License.
34import math
35import os
36import sys
37import warnings
38
39import rospy
40
41from .. import api
42from .. import ros1
43from .. import util
44from . import exceptions
45from . clock import Clock, ClockType
46from . parameter import PARAMETER_SEPARATOR_STRING, FloatingPointRange, IntegerRange, \
47 Parameter, ParameterDescriptor, ParameterValue, SetParametersResult
48from . qos import DurabilityPolicy, QoSPresetProfiles
49from . topic_endpoint_info import TopicEndpointInfo, TopicEndpointTypeEnum
50
51
52
54 """Thrown when a node name is not found."""
55
56
57class Node:
58 """
59 ROS2-like compatitibility class for ROS1.
60
61 Declares the full interface of `rclpy.node.Node`, with partially implemented
62 functionality.
63 """
64
65
66 PARAM_REL_TOL = 1e-6
67
68
69 def __init__(self, node_name, *, context=None, cli_args=None, namespace=None,
70 use_global_arguments=True, enable_rosout=True, start_parameter_services=None,
71 parameter_overrides=None, allow_undeclared_parameters=False,
72 automatically_declare_parameters_from_overrides=False):
73 """
74 Creates a ROS1 node.
75
76 @param node_name a name to give to this node
77 @param context ignored (ROS2 API compatibility stand-in)
78 @param cli_args a list of strings of command line args to be used only by this node;
79 these arguments are used to extract remappings used by the node and other ROS specific
80 settings, as well as user defined non-ROS arguments
81 @param namespace the namespace to which relative topic and service names will be prefixed
82
83 @param use_global_arguments `False` if the node should ignore process-wide command line args
84 @param enable_rosout `False` if the node should ignore rosout logging
85 @param start_parameter_services ignored (ROS2 API compatibility stand-in)
86 @param parameter_overrides list of `Parameter` overrides for initial values
87 of parameters declared on the node
89 @param allow_undeclared_parameters true if undeclared parameters are allowed;
90 this flag affects the behavior of parameter-related operations
91 @param automatically_declare_parameters_from_overrides if True, `parameter_overrides`
92 will be used to implicitly declare
93 parameters on the node
94 """
95 if ros1.MASTER:
96 raise Exception("ROS1 node already created, cannot create another")
97
98 self.__publishers = []
99 self.__subscriptions = []
100 self.__clients = []
101 self.__services = []
102 self.__timers = []
103 self.__executor = None
104 self._parameters = {}
106 self._parameter_overrides = {}
107 self._descriptors = {}
108 self._allow_undeclared_parameters = allow_undeclared_parameters
109
110 if namespace and namespace != "/":
111 os.environ["ROS_NAMESPACE"] = namespace
112 rospy.names._set_caller_id(util.namejoin(namespace, node_name))
113
114 node_args = (sys.argv if use_global_arguments else []) + list(cli_args or [])
115 ros1.init_node(node_name, node_args, enable_rosout=enable_rosout)
116
117 self._parameter_overrides = {k: Parameter(k, value=v)
118 for k, v in ros1.get_params(nested=False)}
119 self._parameter_overrides.update({p.name: p for p in parameter_overrides or {}})
120 if automatically_declare_parameters_from_overrides:
121 self._parameters.update(self._parameter_overrides)
122 self._descriptors.update({p: ParameterDescriptor() for p in self._parameters})
123 for p in parameter_overrides or {}:
124 ros1.set_param(p.name, p.value)
125
126 self._clock = Clock(clock_type=ClockType.ROS_TIME)
128 @property
129 def publishers(self):
130 """Yields publishers that have been created on this node."""
131 yield from self.__publishers
132
133 @property
134 def subscriptions(self):
135 """Yields subscriptions that have been created on this node."""
136 yield from self.__subscriptions
137
138 @property
139 def clients(self):
140 """Yields clients that have been created on this node."""
141 yield from self.__clients
142
143 @property
144 def services(self):
145 """Yields services that have been created on this node."""
146 yield from self.__services
147
148 @property
149 def timers(self):
150 """Yields timers that have been created on this node."""
151 yield from self.__timers
152
153 @property
154 def guards(self):
155 """Yields (ROS2 API compatibility stand-in)."""
156 yield from []
157
158 @property
159 def waitables(self):
160 """Yields (ROS2 API compatibility stand-in)."""
161 yield from []
163 @property
164 def executor(self):
165 """Returns None (ROS2 API compatibility stand-in)."""
166 return self.__executor
167
168 @executor.setter
169 def executor(self, new_executor):
170 """Does nothing (ROS2 API compatibility stand-in)."""
171 self.__executor = new_executor
172
173 @property
174 def context(self):
175 """Returns None (ROS2 API compatibility stand-in)."""
176 return None
177
178 @property
179 def default_callback_group(self):
180 """Returns None (ROS2 API compatibility stand-in)."""
181 return None
182
183 @property
184 def handle(self):
185 """Returns None (ROS2 API compatibility stand-in)."""
186 return None
187
188 @handle.setter
189 def handle(self, value):
190 raise AttributeError("handle cannot be modified after node creation")
191
192 def get_name(self):
193 """Returns the name of the node, without namespace."""
194 return rospy.get_name().rsplit("/", 1)[-1]
195
196 def get_namespace(self):
197 """Returns the namespace of the node."""
198 return "/" + rospy.get_namespace().strip("/")
199
200 def get_clock(self):
201 """Returns `clock.Clock` using ROS time."""
202 return self._clock
204 def get_logger(self):
205 """Get the node's logger."""
206 return ros1.get_logger()
207
208 def declare_parameter(self, name, value=None, descriptor=None, ignore_override=False):
209 """
210 Sets and initializes a node parameter.
211
212 This method, if successful, will result in any callback registered with
213 `add_on_set_parameters_callback` to be called.
214
215 @param name fully-qualified name of the parameter, including its namespace
216 @param value value of the parameter to set, if any
217 @param descriptor `ParameterDescriptor` instance, if any
218 @param ignore_override whether to set value given here, ignoring any overrides
219 @return `Parameter` instance with the final assigned value
220
221 @throws ParameterAlreadyDeclaredException if the parameter has already been set
222 @throws InvalidParameterException if the parameter name is invalid
223 @throws InvalidParameterValueException if a registered callback rejects the parameter
224 """
225 descriptor = descriptor or ParameterDescriptor()
226 return self.declare_parameters("", [(name, value, descriptor)], ignore_override)[0]
227
228 def declare_parameters(self, namespace, parameters, ignore_override=False):
229 """
230 Sets a list of parameters.
231
232 The tuples in the given parameter list shall contain the name for each parameter,
233 optionally providing a value and a descriptor.
234 For each entry in the list, a parameter with a name of "namespace.name"
235 will be set.
236 The resulting value for each set parameter will be returned, considering
237 parameter overrides set upon node creation as the first choice,
238 or provided parameter values as the second one.
239
240 The name expansion is naive, so if you set the namespace to be "foo.",
241 then the resulting parameter names will be like "foo..name".
242 However, if the namespace is an empty string, then no leading '.' will be
243 placed before each name, which would have been the case when naively
244 expanding "namespace.name".
245 This allows you to declare several parameters at once without a namespace.
246
247 This method, if successful, will result in any callback registered with
248 `add_on_set_parameters_callback` to be called once for each parameter.
249 If one of those calls fail, an exception will be raised and the remaining parameters will
250 not be declared.
251 Parameters declared up to that point will not be undeclared.
252
253 @param namespace namespace for parameters (empty string for node root namespace)
254 @param parameters list of tuples with parameters to set,
255 as (name, ) or (name, value) or (name, value, descriptor)
256 @param ignore_override whether to set value given here, ignoring any overrides
257 @return `Parameter` list with the final assigned values
258
259 @throws ParameterAlreadyDeclaredException if a parameter has already been set
260 @throws InvalidParameterException if a parameter name is invalid.
261 @throws InvalidParameterValueException if a registered callback rejects any parameter
262 @throws TypeError if any tuple in `parameters`
263 does not match the annotated type
264 """
265 parameter_list = []
266 descriptors = {}
267 for index, parameter_tuple in enumerate(parameters):
268 if len(parameter_tuple) < 1 or len(parameter_tuple) > 3:
269 raise TypeError(
270 'Invalid parameter tuple length at index {index} in parameters list: '
271 '{parameter_tuple}; expecting length between 1 and 3'.format_map(locals())
272 )
273
274 value = None
275 descriptor = ParameterDescriptor()
276
277 # Get the values from the tuple, checking its types.
278 # Use defaults if the tuple doesn't contain value and / or descriptor.
279 try:
280 name = parameter_tuple[0]
281 assert \
282 isinstance(name, str), \
284 'First element {name} at index {index} in parameters list '
285 'is not a str.'.format_map(locals())
286 )
287
288 # Get value from parameter overrides, of from tuple if it doesn't exist.
289 if not ignore_override and name in self._parameter_overrides:
290 value = self._parameter_overrides[name].value
291 else:
292 # This raises IndexError if value not given
293 value = parameter_tuple[1]
294
295 # Get descriptor from tuple.
296 descriptor = parameter_tuple[2]
297 assert \
298 isinstance(descriptor, ParameterDescriptor), \
299 (
300 'Third element {descriptor} at index {index} in parameters list '
301 'is not a ParameterDescriptor.'.format_map(locals())
302 )
303 except AssertionError as assertion_error:
304 raise TypeError(assertion_error)
305 except IndexError:
306 # This means either value or descriptor were not defined which is fine.
307 pass
308
309 if namespace:
310 name = "%s.%s" % (namespace, name)
311
312 parameter_list.append(Parameter(name, value=value))
313 descriptors.update({name: descriptor})
314
315 parameters_already_declared = [
316 parameter.name for parameter in parameter_list if parameter.name in self._parameters
317 ]
318 if any(parameters_already_declared):
319 raise exceptions.ParameterAlreadyDeclaredException(parameters_already_declared)
320
321 # Call the callback once for each of the parameters, using method that doesn't
322 # check whether the parameter was declared beforehand or not.
323 self._set_parameters(parameter_list, descriptors, raise_on_failure=True,
324 allow_undeclared_parameters=True)
325 return self.get_parameters([parameter.name for parameter in parameter_list])
326
327 def undeclare_parameter(self, name):
328 """
329 Unset a previously set parameter.
330
331 This method will not cause a callback registered with
332 `add_on_set_parameters_callback` to be called.
333
334 @param name fully-qualified name of the parameter, including its namespace
335
336 @throws ParameterNotDeclaredException if the parameter does not exist
337 @throws ParameterImmutableException if the parameter was created as read-only
338 """
339 if self.has_parameter(name):
340 if self._descriptors[name].read_only:
342 else:
343 del self._parameters[name]
344 del self._descriptors[name]
345 ros1.delete_param(name)
346 else:
348
349 def has_parameter(self, name):
350 """
351 Returns whether parameter exists.
352
353 @param name fully-qualified name of the parameter, including its namespace
354 """
355 return name in self._parameters
356
357 def get_parameters(self, names):
358 """
359 Returns a list of parameters.
360
361 @param names fully-qualified names of the parameters to get, including namespaces
362 @return The values for the given parameter names.
363 A default `Parameter` will be returned for undeclared parameters
364 if undeclared parameters are allowed.
365
366 @throws ParameterNotDeclaredException if undeclared parameters are not allowed,
367 and any given parameter is unknown
368 """
369 if not all(isinstance(name, str) for name in names):
370 raise TypeError('All names must be instances of type str')
371 return [self.get_parameter(name) for name in names]
372
373 def get_parameter(self, name):
374 """
375 Returns a parameter by name.
376
377 @param name fully-qualified name of the parameter, including its namespace
378 @return `Parameter` for the given name.
379 A default Parameter will be returned for an undeclared parameter
380 if undeclared parameters are allowed.
381
382 @throws ParameterNotDeclaredException if undeclared parameters are not allowed,
383 and the parameter is unknown
384 """
385 if self.has_parameter(name):
386 return self._parameters[name]
388 return Parameter(name, Parameter.Type.NOT_SET, None)
389 else:
391
392 def get_parameter_or(self, name, alternative_value=None):
393 """
394 Returns a parameter or the alternative value.
395
396 If the alternative value is None, a default `Parameter` with the given name
397 and `NOT_SET` type will be returned if the parameter was not declared.
398
399 @param name fully-qualified name of the parameter, including its namespace
400 @param alternative_value alternative parameter to return if unknown
401 @return requested `Parameter`, or `alternative_value` if unknown
402 """
403 if alternative_value is None:
404 alternative_value = Parameter(name, Parameter.Type.NOT_SET)
405 return self._parameters.get(name, alternative_value)
406
407 def get_parameters_by_prefix(self, prefix):
408 """
409 Get parameters that have a given prefix in their names as a dictionary.
410
411 The names which are used as keys in the returned dictionary have the prefix removed.
412 For example, if you use the prefix "foo" and the parameters "foo.ping", "foo.pong"
413 and "bar.baz" exist, then the returned dictionary will have the keys "ping" and "pong".
414 Note that the parameter separator is also removed from the parameter name to create the
415 keys.
416
417 An empty string for the prefix will match all parameters.
419 If no parameters with the prefix are found, an empty dictionary will be returned.
420
421 @param prefix the prefix of the parameters to get
422 @return list of `Parameter` under the given prefix, with prefix removed from names
423 """
424 parameters_with_prefix = {}
425 if prefix:
426 prefix = prefix + PARAMETER_SEPARATOR_STRING
427 prefix_len = len(prefix)
428 for parameter_name in self._parameters:
429 if parameter_name.startswith(prefix):
430 parameters_with_prefix.update(
431 {parameter_name[prefix_len:]: self._parameters.get(parameter_name)})
432 return parameters_with_prefix
433
434 def set_parameters(self, parameter_list):
435 """
436 Set parameters for the node, and return the result for the set action.
437
438 If any parameter in the list was not declared beforehand and undeclared parameters are not
439 allowed for the node, this method will raise a ParameterNotDeclaredException exception.
440
441 Parameters are set in the order they are declared in the list.
442 If setting a parameter fails due to not being declared, then the
443 parameters which have already been set will stay set, and no attempt will
444 be made to set the parameters which come after.
445
446 If undeclared parameters are allowed, then all the parameters will be implicitly
447 declared before being set even if they were not declared beforehand.
448 Parameter overrides are ignored by this method.
449
450 If a callback was registered previously with `add_on_set_parameters_callback`, it
451 will be called prior to setting the parameters for the node, once for each parameter.
452 If the callback prevents a parameter from being set, then it will be reflected in the
453 returned result; no exceptions will be raised in this case.
454
455 If the value type of the parameter is NOT_SET, and the existing parameter type is
456 something else, then the parameter will be implicitly undeclared.
457
458 @param parameter_list list of `Parameter` to set
459 @return list of `SetParametersResult`, one for each input
460
461 @throws ParameterNotDeclaredException if undeclared parameters are not allowed,
462 and any given parameter is unknown
463 """
464 return self._set_parameters(parameter_list)
465
466 def _set_parameters(self, parameter_list, descriptors=None, raise_on_failure=False,
467 allow_undeclared_parameters=False):
468 """
469 Set parameters for the node, and return the result for the set action.
470
471 Method for internal usage; applies a setter method for each parameters in the list.
472 By default it checks if the parameters were declared, raising an exception if at least
473 one of them was not.
474
475 If a callback was registered previously with `add_on_set_parameters_callback`, it
476 will be called prior to setting the parameters for the node, once for each parameter.
477 If the callback doesn't succeed for a given parameter, it won't be set and either an
478 unsuccessful result will be returned for that parameter, or an exception will be raised
479 according to `raise_on_failure` flag.
480
481 @param parameter_list list of `Parameter` to set.
482 @param descriptors descriptors to set to the given parameters,
483 as `{name: ParameterDescriptor}`,
484 either one for each parameter or none at all
485 @param raise_on_failure raise `InvalidParameterValueException`
486 if any set-parameters callback rejects a parameter
487 @param allow_undeclared_parameters auto-declare unknown parameters
488 @return list of `SetParametersResult`, one for each input
489
490 @throws InvalidParameterValueException if any set-parameters callback rejects a parameter
491 and `raise_on_failure` is true
492 @throws ParameterNotDeclaredException if undeclared parameters are not allowed,
493 and any given parameter is unknown
494 """
495 if descriptors is not None:
496 assert all(parameter.name in descriptors for parameter in parameter_list)
497
498 results = []
499 for param in parameter_list:
500 if not allow_undeclared_parameters:
501 self._check_undeclared_parameters([param])
502 # If undeclared parameters are allowed, parameters with type `NOT_SET` shall be stored.
503 result = self._set_parameters_atomically(
504 [param],
505 descriptors,
506 allow_not_set_type=allow_undeclared_parameters
507 )
508 if raise_on_failure and not result.successful:
509 raise exceptions.InvalidParameterValueException(param.name, param.value, result.reason)
510 results.append(result)
511 return results
512
513 def set_parameters_atomically(self, parameter_list):
514 """
515 Set the given parameters, all at one time, and then aggregate result.
516
517 If any parameter in the list was not declared beforehand and undeclared parameters are not
518 allowed for the node, this method will raise a `ParameterNotDeclaredException` exception.
519
520 Parameters are set all at once.
521 If setting a parameter fails due to not being declared, then no parameter will be set.
522 Either all of the parameters are set or none of them are set.
523
524 If undeclared parameters are allowed for the node, then all the parameters will be
525 implicitly declared before being set even if they were not declared beforehand.
526
527 If a callback was registered previously with `add_on_set_parameters_callback`, it
528 will be called prior to setting the parameters for the node only once for all parameters.
529 If the callback prevents the parameters from being set, then it will be reflected in the
530 returned result; no exceptions will be raised in this case.
531
532 If the value type of the parameter is `NOT_SET`, and the existing parameter type is
533 something else, then the parameter will be implicitly undeclared.
534
535 @param parameter_list list of `Parameter` to set
536 @return a single `SetParametersResult` for all parameters
537
538 @throws ParameterNotDeclaredException if undeclared parameters are not allowed,
539 and any named parameter is unknown
540 """
541 self._check_undeclared_parameters(parameter_list)
542 return self._set_parameters_atomically(parameter_list)
543
544 def _check_undeclared_parameters(self, parameter_list):
545 """
546 Check if all parameters in list have correct types and were declared beforehand.
547
548 @param parameter_list list of `Parameter` to check
549 @throws ParameterNotDeclaredException if any given parameter is unknown
550 """
551 if not all(isinstance(parameter, Parameter) for parameter in parameter_list):
552 raise TypeError("parameter must be instance of type '{}'".format(repr(Parameter)))
553
554 undeclared_parameters = (
555 param.name for param in parameter_list if param.name not in self._parameters
556 )
557 if (not self._allow_undeclared_parameters and any(undeclared_parameters)):
558 raise exceptions.ParameterNotDeclaredException(list(undeclared_parameters))
559
560 def _set_parameters_atomically(self, parameter_list, descriptors=None,
561 allow_not_set_type=False):
562 """
563 Set the given parameters, all at one time, and then aggregate result.
564
565 This internal method does not reject undeclared parameters.
566 If `allow_not_set_type` is False, a parameter with type `NOT_SET` will be undeclared.
567
568 If a callback was registered previously with `add_on_set_parameters_callback`, it
569 will be called prior to setting the parameters for the node only once for all parameters.
570 If the callback prevents the parameters from being set, then it will be reflected in the
571 returned result; no exceptions will be raised in this case.
572
573 @param parameter_list list of `Parameter` to set
574 @param descriptors new descriptors to apply to the parameters before setting them,
575 as `{name: ParameterDescriptor}`,
576 one for each parameter or none at all
577 @param allow_not_set_type whether to store parameters of `NOT_SET` type,
578 or undeclare them if False
579 @return a single `SetParametersResult` for all parameters
580 """
581 if descriptors is not None:
582 # If new descriptors are provided, ensure every parameter has an assigned descriptor
583 # and do not check for read-only.
584 assert all(parameter.name in descriptors for parameter in parameter_list)
585 result = self._apply_descriptors(parameter_list, descriptors, False)
586 else:
587 # If new descriptors are not provided, use existing ones and check for read-only.
588 result = self._apply_descriptors(parameter_list, self._descriptors, True)
589
590 if not result.successful:
591 return result
592 elif self._parameters_callbacks:
593 for callback in self._parameters_callbacks:
594 result = callback(parameter_list)
595 if not result.successful:
596 return result
597 result = SetParametersResult(successful=True)
598
599 if result.successful:
600 for param in parameter_list:
601 # If parameters without type and value are not allowed, they shall be undeclared.
602 if not allow_not_set_type and Parameter.Type.NOT_SET == param.type_:
603 # Parameter deleted. (Parameter had value and new value is not set).
604 # Delete any unset parameters regardless of their previous value.
605 if param.name in self._parameters:
606 del self._parameters[param.name]
607 if param.name in self._descriptors:
608 del self._descriptors[param.name]
609 ros1.delete_param(param.name)
610 else:
611 # Update descriptors; set a default if it doesn't exist.
612 # Don't update if it already exists for the current parameter and a new one
613 # was not specified in this method call.
614 if descriptors is not None:
615 self._descriptors[param.name] = descriptors[param.name]
616 elif param.name not in self._descriptors:
617 self._descriptors[param.name] = ParameterDescriptor()
618
619 # Descriptors have already been applied by this point.
620 self._parameters[param.name] = param
621 ros1.set_param(param.name, param.value)
622
623 return result
624
625 def add_on_set_parameters_callback(self, callback):
626 """
627 Add a callback in front to the list of callbacks.
628
629 @param callback function to call with (`[Parameter]`) when setting any node parameters,
630 returning `SetParametersResult`
631 """
632 self._parameters_callbacks.insert(0, callback)
633
634 def remove_on_set_parameters_callback(self, callback):
635 """
636 Remove a callback from list of callbacks.
637
638 @param callback function registered with `add_on_set_parameters_callback()`
640 @throws ValueError if the callback is unknown
641 """
642 self._parameters_callbacks.remove(callback)
643
644 def _apply_descriptors(self, parameter_list, descriptors, check_read_only=True):
645 """
646 Apply descriptors to parameters and return an aggregated result without saving parameters.
647
648 In case no descriptors are provided to the method, existing descriptors shall be used.
649 In any case, if a given parameter doesn't have a descriptor it shall be skipped.
650
651 @param parameter_list list of `Parameter` to be checked
652 @param descriptors `{name: `ParameterDescriptor}` to apply
653 @param check_read_only whether to check for read-only descriptors
654 @return a single `SetParametersResult` for all checks
656 @throws ParameterNotDeclaredException if a descriptor is not provided,
657 a given parameter is unknown
658 and undeclared parameters are not allowed
659 """
660 for param in parameter_list:
661 if param.name in descriptors:
662 result = self._apply_descriptor(param, descriptors[param.name], check_read_only)
663 if not result.successful:
664 return result
665 return SetParametersResult(successful=True)
666
667 def _apply_descriptor(self, parameter, descriptor=None, check_read_only=True):
668 """
669 Apply a descriptor to a parameter and return a result without saving the parameter.
670
671 This method sets the type in the descriptor to match the parameter type.
672 If a descriptor is provided, its name will be set to the name of the parameter.
673
674 @param parameter `Parameter` to be checked
675 @param descriptor `ParameterDescriptor` to apply,
676 or None to use the stored descriptor
677 @param check_read_only whether to check for read-only descriptor
678 @return a `SetParametersResult` for all checks
679
680 @throws ParameterNotDeclaredException if descriptor is not provided,
681 the given parameter is unknown
682 and undeclared parameters are not allowed
683 """
684 if descriptor is None:
685 descriptor = self.describe_parameter(parameter.name)
686 else:
687 descriptor.name = parameter.name
688
689 # The type in the descriptor has to match the type of the parameter.
690 descriptor.type = parameter.type_.value
691
692 if check_read_only and descriptor.read_only:
693 return SetParametersResult(
694 successful=False,
695 reason='Trying to set a read-only parameter: {}.'.format(parameter.name))
696
697 if parameter.type_ == Parameter.Type.INTEGER and descriptor.integer_range:
698 return self._apply_integer_range(parameter, descriptor.integer_range[0])
700 if parameter.type_ == Parameter.Type.DOUBLE and descriptor.floating_point_range:
701 return self._apply_floating_point_range(parameter, descriptor.floating_point_range[0])
702
703 return SetParametersResult(successful=True)
704
705 def _apply_integer_range(self, parameter, integer_range):
706 """
707 Returns whether parameter value passes integer range check.
708
709 Value must fall into given min-max range, endpoints included,
710 and be an exact number of steps from range start if range has step defined.
711
712 @param parameter `Parameter` to check
713 @param integer_range `IntegerRange` to use
714 @return `SetParametersResult` with success or failure reason
715 """
716 min_value = min(integer_range.from_value, integer_range.to_value)
717 max_value = max(integer_range.from_value, integer_range.to_value)
718
719 # Values in the edge are always OK.
720 if parameter.value == min_value or parameter.value == max_value:
721 return SetParametersResult(successful=True)
722
723 if not min_value < parameter.value < max_value:
724 return SetParametersResult(
725 successful=False,
726 reason='Parameter {} out of range. '
727 'Min: {}, Max: {}, value: {}'.format(
728 parameter.name, min_value, max_value, parameter.value
729 )
730 )
731
732 if integer_range.step != 0 and (parameter.value - min_value) % integer_range.step != 0:
733 return SetParametersResult(
734 successful=False,
735 reason='The parameter value for {} is not a valid step. '
736 'Min: {}, max: {}, value: {}, step: {}'.format(
737 parameter.name,
738 min_value,
739 max_value,
740 parameter.value,
741 integer_range.step
742 )
743 )
744
745 return SetParametersResult(successful=True)
746
747 def _apply_floating_point_range(self, parameter, floating_point_range):
748 """
749 Returns whether parameter value passes floating-point range check.
750
751 Value must fall into given min-max range, endpoints included,
752 and be a tolerably exact number of steps from range start if range has step defined.
753
754 @param parameter `Parameter` to check
755 @param floating_point_range `FloatingPointRange` to use
756 @return `SetParametersResult` with success or failure reason
757 """
758 min_value = min(floating_point_range.from_value, floating_point_range.to_value)
759 max_value = max(floating_point_range.from_value, floating_point_range.to_value)
760
761 # Values in the edge are always OK.
762 if (
763 math.isclose(parameter.value, min_value, rel_tol=self.PARAM_REL_TOL) or
764 math.isclose(parameter.value, max_value, rel_tol=self.PARAM_REL_TOL)
765 ):
766 return SetParametersResult(successful=True)
767
768 if not min_value < parameter.value < max_value:
769 return SetParametersResult(
770 successful=False,
771 reason='Parameter {} out of range '
772 'Min: {}, Max: {}, value: {}'.format(
773 parameter.name, min_value, max_value, parameter.value
774 )
776
777 if floating_point_range.step != 0.0:
778 distance_int_steps = round((parameter.value - min_value) / floating_point_range.step)
779 if not math.isclose(
780 min_value + distance_int_steps * floating_point_range.step,
781 parameter.value,
782 rel_tol=self.PARAM_REL_TOL
783 ):
784 return SetParametersResult(
785 successful=False,
786 reason='The parameter value for {} is not close enough to a valid step. '
787 'Min: {}, max: {}, value: {}, step: {}'.format(
788 parameter.name,
789 min_value,
790 max_value,
791 parameter.value,
792 floating_point_range.step
793 )
794 )
795
796 return SetParametersResult(successful=True)
797
798 def _apply_descriptor_and_set(self, parameter, descriptor=None, check_read_only=True):
799 """
800 Apply parameter descriptor and set parameter if successful.
801
802 @param parameter `Parameter` to be checked
803 @param descriptor `ParameterDescriptor` to apply,
804 or None to use the stored descriptor
805 @param check_read_only whether to check for read-only descriptors
806 """
807 result = self._apply_descriptor(parameter, descriptor, check_read_only)
808 if result.successful:
809 self._parameters[parameter.name] = parameter
810 return result
811
812 def describe_parameter(self, name):
813 """
814 Get the parameter descriptor of a given parameter.
815
816 @param name fully-qualified name of the parameter, including its namespace
817 @return `ParameterDescriptor` corresponding to the parameter,
818 or default `ParameterDescriptor` if parameter is unknown
819 and undeclared parameters are allowed
820
821 @throws ParameterNotDeclaredException if parameter is unknown
822 and undeclared parameters are not allowed
823 """
824 try:
825 return self._descriptors[name]
826 except KeyError:
828 return ParameterDescriptor()
829 else:
831
832 def describe_parameters(self, names):
833 """
834 Get the parameter descriptors of a given list of parameters.
835
836 @param name list of fully-qualified names of the parameters to describe
837 @return list of `ParameterDescriptor` corresponding to the given parameters.
838 Default `ParameterDescriptor` shall be returned for parameters that
839 had not been declared before if undeclared parameters are allowed.
840
841 @throws ParameterNotDeclaredException if any parameter is unknown
842 and undeclared parameters are not allowed
843 """
844 parameter_descriptors = []
845 for name in names:
846 parameter_descriptors.append(self.describe_parameter(name))
847 return parameter_descriptors
848
849 def set_descriptor(self, name, descriptor, alternative_value=None):
850 """
851 Set a new descriptor for a given parameter.
852
853 The name in the descriptor is ignored and set to given `name`.
854
855 @param name fully-qualified name of the parameter to set the descriptor to
856 @param descriptor new `ParameterDescriptor` to apply to the parameter
857 @param alternative_value `ParameterValue` to set to the parameter
858 if the existing value does not comply with the new descriptor
859 @return `ParameterValue` for the given parameter
860
861 @throws ParameterNotDeclaredException if the parameter is unknown
862 and undeclared parameters are not allowed
863 @throws ParameterImmutableException if the parameter exists and is read-only
864 @throws ParameterValueException if neither the existing value nor the alternative value
865 comply with the provided descriptor
866 """
867 if not self.has_parameter(name):
870 else:
871 return self.get_parameter(name).get_parameter_value()
872
873 if self.describe_parameter(name).read_only:
875
876 current_parameter = self.get_parameter(name)
877 if alternative_value is None:
878 alternative_parameter = current_parameter
879 else:
880 alternative_parameter = Parameter(name=name, value=alternative_value.get_value())
881
882 # First try keeping the parameter, then try the alternative one.
883 # Don't check for read-only since we are applying a new descriptor now.
884 if not self._apply_descriptor_and_set(current_parameter, descriptor, False).successful:
885 alternative_set_result = (
886 self._apply_descriptor_and_set(alternative_parameter, descriptor, False)
887 )
888 if not alternative_set_result.successful:
890 name,
891 alternative_parameter.value,
892 alternative_set_result.reason
893 )
894
895 self._descriptors[name] = descriptor
896 return self.get_parameter(name).get_parameter_value()
897
898 def set_parameters_callback(self, callback):
899 """
900 Register a set parameters callback.
901
902 @deprecated Since Foxy. Use `add_on_set_parameters_callback()` instead.
903
904 Calling this function will add a callback to the self._parameter_callbacks list.
905
906 @param callback function to call with `([`Parameter`])` when setting any node parameters,
907 returning `SetParametersResult`
908 """
909 warnings.warn(
910 'set_parameters_callback() is deprecated. '
911 'Use add_on_set_parameters_callback() instead'
912 )
913 self._parameters_callbacks = [callback]
914
915 def add_waitable(self, waitable):
916 """Does nothing (ROS2 API compatibility stand-in)."""
917
918 def remove_waitable(self, waitable):
919 """Does nothing (ROS2 API compatibility stand-in)."""
920
921 def create_publisher(self, msg_type, topic, qos_profile,
922 *, callback_group=None, event_callbacks=None):
923 """
924 Creates a new publisher.
925
926 @param msg_type type class of ROS messages the publisher will publish
927 @param topic the name of the topic the publisher will publish to
928 @param qos_profile a `QoSProfile` or a queue size to apply to the publisher,
929 publisher will be latched if `durability` is `TRANSIENT_LOCAL`
930 @param callback_group ignored (ROS2 API compatibility stand-in)
931 @param event_callbacks ignored (ROS2 API compatibility stand-in)
932 @return `rospy.Publisher` instance
933 """
934 queue_size = qos_profile if isinstance(qos_profile, int) else qos_profile.depth
935 latch = False
936 if not isinstance(qos_profile, int):
937 latch = (DurabilityPolicy.TRANSIENT_LOCAL == qos_profile.durability)
938 pub = ros1.create_publisher(topic, msg_type, latch=latch, queue_size=queue_size)
939 self.__publishers.append(pub)
940 return pub
941
942 def create_subscription(self, msg_type, topic, callback, qos_profile,
943 *, callback_group=None, event_callbacks=None, raw=False):
944 """
945 Creates a new subscription.
946
947 @param msg_type type class of ROS messages the subscription will subscribe to.
948 @param topic the name of the topic the subscription will subscribe to
949 @param callback a user-defined callback function that is called when a message is
950 received by the subscription
951 @param qos_profile a `QoSProfile` or a queue size to apply to the subscription
952 @param callback_group ignored (ROS2 API compatibility stand-in)
953 @param event_callbacks ignored (ROS2 API compatibility stand-in)
954 @param raw if `True`, then subscription will be done with `rospy.AnyMsg`,
955 providing message raw binary bytes
956 @return `rospy.Subscriber` instance
957 """
958 queue_size = qos_profile if isinstance(qos_profile, int) else qos_profile.depth
959 sub = ros1.create_subscriber(topic, msg_type, callback=callback,
960 queue_size=queue_size, raw=raw)
961 self.__subscriptions.append(sub)
962 return sub
963
964 def create_client(self, srv_type, srv_name, *, qos_profile=None, callback_group=None):
965 """
966 Creates a new service client.
967
968 @param srv_type type class of the service, like `std_srvs.srv.Trigger`
969 @param srv_name the name of the service
970 @param qos_profile ignored (ROS2 API compatibility stand-in)
971 @param callback_group ignored (ROS2 API compatibility stand-in)
972 @return `rospy.ServiceProxy` instance
973 """
974 client = ros1.create_client(srv_name, srv_type)
975 self.__clients.append(client)
976 return client
977
978 def create_service(self, srv_type, srv_name, callback,
979 *, qos_profile=None, callback_group=None):
980 """
981 Creates a new service server.
982
983 @param srv_type type class of the service, like `std_srvs.srv.Trigger`
984 @param srv_name the name of the service
985 @param callback a user-defined callback function that is called when a service request
986 is received by the server, as callback(request, response)
987 @param qos_profile ignored (ROS2 API compatibility stand-in)
988 @param callback_group ignored (ROS2 API compatibility stand-in)
989 @return `rospy.Service` instance
990 """
991 service = ros1.create_service(srv_name, srv_type, callback)
992 self.__services.append(service)
993 return service
994
995 def create_timer(self, timer_period_sec, callback, callback_group=None, clock=None):
996 """
997 Creates a new timer.
998
999 The timer will be started and every `timer_period_sec` number of seconds the provided
1000 callback function will be called.
1002 @param timer_period_sec the period (s) of the timer
1003 @param callback a user-defined callback function that is called when the timer expires
1004 @param callback_group ignored (ROS2 API compatibility stand-in)
1005 @param clock the clock which the timer gets time from
1006 @return `rospy.Timer` instance
1007 """
1008 timer = ros1.create_timer(timer_period_sec, callback)
1009 timer._clock = clock or self._clock
1010 self.__timers.append(timer)
1011 return timer
1012
1013 def create_guard_condition(self, callback, callback_group=None):
1014 """Does nothing and returns None (ROS2 API compatibility stand-in)."""
1015 return None
1016
1017 def create_rate(self, frequency, clock=None):
1018 """
1019 Creates a rate object.
1020
1021 The timer will be started and every `timer_period_sec` number of seconds the provided
1022 callback function will be called.
1023
1024 @param frequency the frequency the Rate runs at (Hz)
1025 @param clock ignored (ROS2 API compatibility stand-in)
1026 @return `rospy.Rate` instance
1027 """
1028 if frequency <= 0:
1029 raise ValueError('frequency must be > 0')
1030 return ros1.create_rate(frequency)
1031
1032 def destroy_publisher(self, publisher):
1033 """
1034 Destroy a publisher created by the node.
1035
1036 @return `True` if successful, `False` otherwise
1037 """
1038 publisher.unregister()
1039 if publisher in self.__publishers:
1040 self.__publishers.remove(publisher)
1041 return True
1042 return False
1043
1044 def destroy_subscription(self, subscription):
1045 """
1046 Destroy a subscription created by the node.
1048 @return `True` if successful, `False` otherwise
1049 """
1050 subscription.unregister()
1051 if subscription in self.__subscriptions:
1052 self.__subscriptions.remove(subscription)
1053 return True
1054 return False
1055
1056 def destroy_client(self, client):
1057 """
1058 Destroy a service client created by the node.
1060 @return `True` if successful, `False` otherwise
1061 """
1062 client.close()
1063 if client in self.__clients:
1064 self.__clients.remove(client)
1065 return True
1066 return False
1067
1068 def destroy_service(self, service):
1069 """
1070 Destroy a service server created by the node.
1072 @return `True` if successful, `False` otherwise
1073 """
1074 service.shutdown()
1075 if service in self.__services:
1076 self.__services.remove(service)
1077 return True
1078 return False
1079
1080 def destroy_timer(self, timer):
1081 """
1082 Destroy a timer created by the node.
1084 @return `True` if successful, `False` otherwise
1085 """
1086 timer.shutdown()
1087 if timer in self.__timers:
1088 self.__timers.remove(timer)
1089 return False
1090
1091 def destroy_guard_condition(self, guard):
1092 """
1093 Does nothing (ROS2 API compatibility stand-in).
1094
1095 :return: ``True``
1096 """
1097 return True
1098
1099 def destroy_rate(self, rate):
1100 """
1101 Does nothing (ROS2 API compatibility stand-in).
1102
1103 :return: `True`
1104 """
1105 return True
1107 def destroy_node(self):
1108 """
1109 Destroys the node and shuts down rospy.
1110
1111 Frees resources used by the node, including any entities created by the following methods:
1112
1113 * `create_publisher`
1114 * `create_subscription`
1115 * `create_client`
1116 * `create_service`
1117 * `create_timer`
1118
1119 """
1120 while self.__publishers:
1121 self.__publishers.pop().unregister()
1122 while self.__subscriptions:
1123 self.__subscriptions.pop().unregister()
1124 while self.__clients:
1125 self.__clients.pop().close()
1126 while self.__services:
1127 self.__services.pop().shutdown()
1128 while self.__timers:
1129 self.__timers.pop().shutdown()
1130 rospy.signal_shutdown(reason="")
1131
1132 def get_publisher_names_and_types_by_node(self, node_name, node_namespace, no_demangle=False):
1133 """
1134 Gets a list of discovered topics for publishers of a remote node.
1135
1136 @param node_name name of a remote node to get publishers for
1137 @param node_namespace namespace of the remote node
1138 @param no_demangle ignored (ROS2 API compatibility stand-in)
1139 @return list of tuples, the first element of each tuple is the topic name
1140 and the second element is a list of topic types
1141
1142 @throws NodeNameNonExistentError if the node wasn't found
1143 @throws RuntimeError unexpected failure
1144 """
1145 node_topics = {}
1146 node_name = util.namejoin(node_namespace, node_name)
1147 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1148 try: state = ros1.MASTER.getSystemState()[-1]
1149 except Exception as e: raise RuntimeError(e)
1150 for topic, nodes in state[0]:
1151 if node_name in nodes:
1152 node_topics.setdefault(topic, [])
1153 if not node_topics and not any(node_name in nn for lst in state[1:] for _, nn in lst):
1155 "Cannot get publisher names and types for nonexistent node", node_name)
1156 try: topics_types = ros1.MASTER.getTopicTypes()[-1] if node_topics else ()
1157 except Exception as e: raise RuntimeError(e)
1158 for topic, typename in topics_types:
1159 if topic in node_topics:
1160 node_topics[topic].append(typename)
1161 return sorted((t, sorted(nn)) for t, nn in node_topics.items())
1162
1163
1164 def get_subscriber_names_and_types_by_node(self, node_name, node_namespace, no_demangle=False):
1165 """
1166 Gets a list of discovered topics for subscriptions of a remote node.
1167
1168 @param node_name name of a remote node to get subscriptions for
1169 @param node_namespace namespace of the remote node
1170 @param no_demangle ignored (ROS2 API compatibility stand-in)
1171 @return list of tuples, the first element of each tuple is the topic name
1172 and the second element is a list of topic types
1173
1174 @throws NodeNameNonExistentError if the node wasn't found
1175 @throws RuntimeError unexpected failure
1176 """
1177 node_topics = {}
1178 node_name = util.namejoin(node_namespace, node_name)
1179 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1180 try: state = ros1.MASTER.getSystemState()[-1]
1181 except Exception as e: raise RuntimeError(e)
1182 for topic, nodes in state[1]:
1183 if node_name in nodes:
1184 node_topics.setdefault(topic, [])
1185 if not node_topics and not any(node_name in nn for lst in state[::2] for _, nn in lst):
1187 "Cannot get subscriber names and types for nonexistent node", node_name)
1188 try: topics_types = ros1.MASTER.getTopicTypes()[-1] if node_topics else ()
1189 except Exception as e: raise RuntimeError(e)
1190 for topic, typename in topics_types:
1191 if topic in node_topics:
1192 node_topics[topic].append(typename)
1193 return sorted((t, sorted(nn)) for t, nn in node_topics.items())
1194
1195
1196 def get_service_names_and_types_by_node(self, node_name, node_namespace):
1197 """
1198 Gets a list of discovered service server topics for a remote node.
1199
1200 @param node_name name of a remote node to get services for
1201 @param node_namespace namespace of the remote node
1202 @return list of tuples,
1203 the first element of each tuple is the service server name
1204 and the second element is a list of service types
1205
1206 @throws NodeNameNonExistentError if the node wasn't found
1207 @throws RuntimeError unexpected failure
1208 """
1209 node_services = {}
1210 node_name = util.namejoin(node_namespace, node_name)
1211 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1212 try: state = ros1.MASTER.getSystemState()[-1]
1213 except Exception as e: raise RuntimeError(e)
1214 for topic, nodes in state[2]:
1215 if node_name in nodes:
1216 node_services.setdefault(topic, [])
1217 if not node_services and not any(node_name in nn for lst in state[::2] for _, nn in lst):
1219 "Cannot get service names and types for nonexistent node", node_name)
1220 for service in list(node_services):
1221 try: node_services[service].append(api.make_full_typename(service, "srv"))
1222 except Exception as e: raise RuntimeError(e)
1223 return sorted((t, sorted(nn)) for t, nn in node_services.items())
1224
1225 def get_client_names_and_types_by_node(self, node_name, node_namespace):
1226 """
1227 Returns an empty list (ROS2 API compatibility stand-in)
1228
1229 ROS1 does not provide service clients information.
1230
1231 @param node_name ignored
1232 @param node_namespace ignored
1233 @return `[]`
1234 """
1235 return []
1236
1237 def get_topic_names_and_types(self, no_demangle=False):
1238 """
1239 Gets a list of available topic names and types.
1241 @param no_demangle ignored (ROS2 API compatibility stand-in)
1242 @return list of tuples, the first element of each tuple is the topic name
1243 and the second element is a list of topic types
1244 """
1245 return ros1.get_topics()
1246
1248 """
1249 Gets a list of available services.
1250
1251 @return list of tuples, the first element of each tuple is the service name
1252 and the second element is a list of service types
1253 """
1254 return ros1.get_services()
1255
1256 def get_node_names(self):
1257 """
1258 Get a list of names for discovered nodes.
1259
1260 @return list of node names without namespaces
1261 """
1262 return [util.namesplit(n)[-1] for n in ros1.get_nodes()]
1263
1265 """
1266 Get a list of names and namespaces for discovered nodes.
1267
1268 @return list of tuples containing two strings: the node name and node namespace
1269 """
1270 return [util.namesplit(n)[::-1] for n in ros1.get_nodes()]
1271
1273 """
1274 Get a list of names, namespaces and enclaves for discovered nodes.
1275
1276 @return list of tuples containing three strings: the node name, node namespace
1277 and enclave (the latter always "/" in ROS1)
1278 """
1279 return [util.namesplit(n)[::-1] + ("/", ) for n in ros1.get_nodes()]
1280
1281 def count_publishers(self, topic_name):
1282 """
1283 Return the number of publishers on a given topic, globally.
1284
1285 `topic_name` may be a relative, private, or fully qualifed topic name.
1286 A relative or private topic is expanded using this node's namespace and name.
1287 The queried topic name is not remapped.
1288
1289 @param topic_name the topic_name on which to count the number of publishers
1290 @return the number of publishers on the topic
1291 """
1292 topic_name = ros1.resolve_name(topic_name)
1293 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1294 nodes = sum((nn for t, nn in ros1.MASTER.getSystemState()[-1][0] if t == topic_name), [])
1295 return len(nodes)
1296
1297 def count_subscribers(self, topic_name):
1298 """
1299 Return the number of subscribers on a given topic.
1300
1301 `topic_name` may be a relative, private, or fully qualifed topic name.
1302 A relative or private topic is expanded using this node's namespace and name.
1303 The queried topic name is not remapped.
1304
1305 @param topic_name the topic_name on which to count the number of subscribers
1306 @return the number of subscribers on the topic
1307 """
1308 topic_name = ros1.resolve_name(topic_name)
1309 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1310 nodes = sum((nn for t, nn in ros1.MASTER.getSystemState()[-1][1] if t == topic_name), [])
1311 return len(nodes)
1312
1313 def _get_info_by_topic(self, topic_name, endpoint_type, no_mangle):
1314 """
1315 Returns a list of `TopicEndpointInfo`.
1316
1317 @param endpoint_type one of TopicEndpointTypeEnum
1318 @param no_mangle whether topic name should be used as is,
1319 by default it will be namespaced under node and remapped
1320 """
1321 endpoints = []
1322 if not no_mangle:
1323 topic_name = ros1.remap_name(ros1.resolve_name(topic_name))
1324 IDX = 0 if TopicEndpointTypeEnum.PUBLISHER == endpoint_type else 1
1325
1326 # getSystemState() returns [[topic, [publishing node, ]], [..subs], [..services]]
1327 nodes = sum((nn for t, nn in ros1.MASTER.getSystemState()[-1][IDX] if t == topic_name), [])
1328 if nodes:
1329 typename = next(nn[0] for t, nn in ros1.get_topics() if t == topic_name)
1330 for node_name in nodes:
1331 kws = dict(zip(("node_name", "node_namespace"), util.namesplit(node_name)))
1332 kws.update(topic_type=typename, endpoint_type=endpoint_type,
1333 qos_profile=QoSPresetProfiles.SYSTEM_DEFAULT.value)
1334 endpoints.append(TopicEndpointInfo(**kws))
1335 return endpoints
1336
1337 def get_publishers_info_by_topic(self, topic_name, no_mangle=False):
1338 """
1339 Return a list of publishers on a given topic.
1340
1341 The returned parameter is a list of TopicEndpointInfo objects, where each will contain
1342 the node name, node namespace, topic type, topic endpoint's GID, and its QoS profile.
1343
1344 `topic_name` may be a relative, private, or fully qualified topic name.
1345 A relative or private topic will be expanded using this node's namespace and name.
1346 The queried `topic_name` is not remapped.
1347
1348 @param topic_name the topic_name on which to find the publishers
1349 @param no_mangle whether topic name should be used as is,
1350 by default it will be namespaced under node and remapped
1352 for all the publishers on this topic
1353 """
1354 return self._get_info_by_topic(topic_name, TopicEndpointTypeEnum.PUBLISHER, no_mangle)
1355
1356 def get_subscriptions_info_by_topic(self, topic_name, no_mangle=False):
1357 """
1358 Return a list of subscriptions on a given topic.
1359
1360 The returned parameter is a list of TopicEndpointInfo objects, where each will contain
1361 the node name, node namespace, topic type, topic endpoint's GID, and its QoS profile.
1362
1363 When the `no_mangle` parameter is `true`, the provided `topic_name` should be a valid topic
1364 name for the middleware (useful when combining ROS with native middleware (e.g. DDS) apps).
1365 When the `no_mangle` parameter is `false`, the provided `topic_name` should follow
1366 ROS topic name conventions.
1367
1368 `topic_name` may be a relative, private, or fully qualified topic name.
1369 A relative or private topic will be expanded using this node's namespace and name.
1370 The queried `topic_name` is not remapped.
1371
1372 @param topic_name the topic_name on which to find the subscriptions
1373 @param no_mangle whether topic name should be used as is,
1374 by default it will be namespaced under node and remapped
1376 for all the subscriptions on this topic
1377 """
1378 return self._get_info_by_topic(topic_name, TopicEndpointTypeEnum.SUBSCRIPTION, no_mangle)
1380
1381__all__ = [
1382 "PARAMETER_SEPARATOR_STRING", "FloatingPointRange", "IntegerRange",
1383 "NodeNameNonExistentError", "Node", "Parameter", "ParameterDescriptor", "ParameterValue",
1384 "SetParametersResult"
1385]
Simple clock interface mimicking `rclpy.clock.Clock`, only providing `now()`.
Definition clock.py:35
Raised when a parameter is rejected by a user callback or when applying a descriptor.
Raised when declaring a parameter that had been declared before.
Raised when a read-only parameter is modified.
Raised when handling an undeclared parameter when it is not allowed.
Definition exceptions.py:97
count_subscribers(self, topic_name)
Return the number of subscribers on a given topic.
Definition node.py:1310
get_client_names_and_types_by_node(self, node_name, node_namespace)
Returns an empty list (ROS2 API compatibility stand-in)
Definition node.py:1240
destroy_client(self, client)
Destroy a service client created by the node.
Definition node.py:1071
set_parameters_atomically(self, parameter_list)
Set the given parameters, all at one time, and then aggregate result.
Definition node.py:554
__init__(self, node_name, *context=None, cli_args=None, namespace=None, use_global_arguments=True, enable_rosout=True, start_parameter_services=None, parameter_overrides=None, allow_undeclared_parameters=False, automatically_declare_parameters_from_overrides=False)
Creates a ROS1 node.
Definition node.py:91
remove_on_set_parameters_callback(self, callback)
Remove a callback from list of callbacks.
Definition node.py:655
_apply_descriptor_and_set(self, parameter, descriptor=None, check_read_only=True)
Apply parameter descriptor and set parameter if successful.
Definition node.py:826
waitables
Yields (ROS2 API compatibility stand-in).
Definition node.py:169
guards
Yields (ROS2 API compatibility stand-in).
Definition node.py:162
_apply_descriptor(self, parameter, descriptor=None, check_read_only=True)
Apply a descriptor to a parameter and return a result without saving the parameter.
Definition node.py:699
_check_undeclared_parameters(self, parameter_list)
Check if all parameters in list have correct types and were declared beforehand.
Definition node.py:565
undeclare_parameter(self, name)
Unset a previously set parameter.
Definition node.py:357
_apply_descriptors(self, parameter_list, descriptors, check_read_only=True)
Apply descriptors to parameters and return an aggregated result without saving parameters.
Definition node.py:674
destroy_subscription(self, subscription)
Destroy a subscription created by the node.
Definition node.py:1059
create_service(self, srv_type, srv_name, callback, *qos_profile=None, callback_group=None)
Creates a new service server.
Definition node.py:1002
get_service_names_and_types_by_node(self, node_name, node_namespace)
Gets a list of discovered service server topics for a remote node.
Definition node.py:1215
has_parameter(self, name)
Returns whether parameter exists.
Definition node.py:373
context
Returns None (ROS2 API compatibility stand-in).
Definition node.py:189
get_parameters_by_prefix(self, prefix)
Get parameters that have a given prefix in their names as a dictionary.
Definition node.py:438
set_parameters(self, parameter_list)
Set parameters for the node, and return the result for the set action.
Definition node.py:477
destroy_service(self, service)
Destroy a service server created by the node.
Definition node.py:1083
set_parameters_callback(self, callback)
Register a set parameters callback.
Definition node.py:924
describe_parameters(self, names)
Get the parameter descriptors of a given list of parameters.
Definition node.py:861
subscriptions
Yields subscriptions that have been created on this node.
Definition node.py:134
destroy_publisher(self, publisher)
Destroy a publisher created by the node.
Definition node.py:1047
create_publisher(self, msg_type, topic, qos_profile, *callback_group=None, event_callbacks=None)
Creates a new publisher.
Definition node.py:948
handle
Returns None (ROS2 API compatibility stand-in).
Definition node.py:203
create_timer(self, timer_period_sec, callback, callback_group=None, clock=None)
Creates a new timer.
Definition node.py:1018
get_publisher_names_and_types_by_node(self, node_name, node_namespace, no_demangle=False)
Gets a list of discovered topics for publishers of a remote node.
Definition node.py:1153
executor
Returns None (ROS2 API compatibility stand-in).
Definition node.py:176
services
Yields services that have been created on this node.
Definition node.py:148
_apply_integer_range(self, parameter, integer_range)
Returns whether parameter value passes integer range check.
Definition node.py:732
destroy_guard_condition(self, guard)
Does nothing (ROS2 API compatibility stand-in).
Definition node.py:1106
add_waitable(self, waitable)
Does nothing (ROS2 API compatibility stand-in).
Definition node.py:931
_set_parameters_atomically(self, parameter_list, descriptors=None, allow_not_set_type=False)
Set the given parameters, all at one time, and then aggregate result.
Definition node.py:596
create_guard_condition(self, callback, callback_group=None)
Does nothing and returns None (ROS2 API compatibility stand-in).
Definition node.py:1024
create_client(self, srv_type, srv_name, *qos_profile=None, callback_group=None)
Creates a new service client.
Definition node.py:986
clients
Yields clients that have been created on this node.
Definition node.py:141
destroy_timer(self, timer)
Destroy a timer created by the node.
Definition node.py:1095
get_subscriber_names_and_types_by_node(self, node_name, node_namespace, no_demangle=False)
Gets a list of discovered topics for subscriptions of a remote node.
Definition node.py:1184
get_clock(self)
Returns `clock.Clock` using ROS time.
Definition node.py:221
get_publishers_info_by_topic(self, topic_name, no_mangle=False)
Return a list of publishers on a given topic.
Definition node.py:1356
get_service_names_and_types(self)
Gets a list of available services.
Definition node.py:1258
get_node_names(self)
Get a list of names for discovered nodes.
Definition node.py:1266
remove_waitable(self, waitable)
Does nothing (ROS2 API compatibility stand-in).
Definition node.py:935
count_publishers(self, topic_name)
Return the number of publishers on a given topic, globally.
Definition node.py:1295
destroy_rate(self, rate)
Does nothing (ROS2 API compatibility stand-in).
Definition node.py:1114
int PARAM_REL_TOL
Relative tolerance for floating-point parameter range steps.
Definition node.py:66
declare_parameters(self, namespace, parameters, ignore_override=False)
Sets a list of parameters.
Definition node.py:283
create_subscription(self, msg_type, topic, callback, qos_profile, *callback_group=None, event_callbacks=None, raw=False)
Creates a new subscription.
Definition node.py:971
get_parameters(self, names)
Returns a list of parameters.
Definition node.py:386
declare_parameter(self, name, value=None, descriptor=None, ignore_override=False)
Sets and initializes a node parameter.
Definition node.py:244
get_parameter(self, name)
Returns a parameter by name.
Definition node.py:401
describe_parameter(self, name)
Get the parameter descriptor of a given parameter.
Definition node.py:842
create_rate(self, frequency, clock=None)
Creates a rate object.
Definition node.py:1037
get_node_names_and_namespaces(self)
Get a list of names and namespaces for discovered nodes.
Definition node.py:1274
timers
Yields timers that have been created on this node.
Definition node.py:155
publishers
Yields publishers that have been created on this node.
Definition node.py:127
_set_parameters(self, parameter_list, descriptors=None, raise_on_failure=False, allow_undeclared_parameters=False)
Set parameters for the node, and return the result for the set action.
Definition node.py:509
_get_info_by_topic(self, topic_name, endpoint_type, no_mangle)
Returns a list of `TopicEndpointInfo`.
Definition node.py:1324
destroy_node(self)
Destroys the node and shuts down rospy.
Definition node.py:1129
add_on_set_parameters_callback(self, callback)
Add a callback in front to the list of callbacks.
Definition node.py:646
_apply_floating_point_range(self, parameter, floating_point_range)
Returns whether parameter value passes floating-point range check.
Definition node.py:775
get_topic_names_and_types(self, no_demangle=False)
Gets a list of available topic names and types.
Definition node.py:1249
get_parameter_or(self, name, alternative_value=None)
Returns a parameter or the alternative value.
Definition node.py:418
default_callback_group
Returns None (ROS2 API compatibility stand-in).
Definition node.py:196
get_node_names_and_namespaces_with_enclaves(self)
Get a list of names, namespaces and enclaves for discovered nodes.
Definition node.py:1283
set_descriptor(self, name, descriptor, alternative_value=None)
Set a new descriptor for a given parameter.
Definition node.py:883
get_subscriptions_info_by_topic(self, topic_name, no_mangle=False)
Return a list of subscriptions on a given topic.
Definition node.py:1379
Thrown when a node name is not found.
Definition node.py:53
This is the message to communicate a parameter's descriptor.
Definition parameter.py:217
ROS node parameter, a stand-in for ROS2 `rclpy.parameter.Parameter` in ROS1.
Definition parameter.py:42
This is the message to communicate the result of setting parameters.
Definition parameter.py:249
get_logger()
Returns `logging.Logger` for logging to ROS log handler.
Definition core.py:307
get_namespace()
Returns ROS node namespace.
Definition core.py:316
shutdown(*context=None)
Sends the shutdown signal to rospy.
Definition rclify.py:148