2Partial stand-in of ROS2 `rclpy.node` for ROS1.
4Heavily modified copy from ROS2 `rclpy.node`,
5at https://github.com/ros2/rclpy (`rclpy/rclpy/node.py`),
6released under the Apache 2.0 License.
8------------------------------------------------------------------------------
9This file is part of rosros - simple unified interface to ROS1 / ROS2.
10Released under the BSD License.
15------------------------------------------------------------------------------
17## @namespace rosros.rclify.node
19# Original file copyright notice:
21# Copyright 2016 Open Source Robotics Foundation, Inc.
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
27# http://www.apache.org/licenses/LICENSE-2.0
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
54 """Thrown when a node name is not found."""
59 ROS2-like compatitibility class for ROS1.
61 Declares the full interface of `rclpy.node.Node`,
with partially implemented
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):
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
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
96 raise Exception(
"ROS1 node already created, cannot create another")
110 if namespace
and namespace !=
"/":
111 os.environ[
"ROS_NAMESPACE"] = namespace
112 rospy.names._set_caller_id(util.namejoin(namespace, node_name))
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)
118 for k, v
in ros1.get_params(nested=
False)}
120 if automatically_declare_parameters_from_overrides:
123 for p
in parameter_overrides
or {}:
124 ros1.set_param(p.name, p.value)
130 """Yields publishers that have been created on this node."""
135 """Yields subscriptions that have been created on this node."""
140 """Yields clients that have been created on this node."""
145 """Yields services that have been created on this node."""
150 """Yields timers that have been created on this node."""
155 """Yields (ROS2 API compatibility stand-in)."""
160 """Yields (ROS2 API compatibility stand-in)."""
165 """Returns None (ROS2 API compatibility stand-in)."""
170 """Does nothing (ROS2 API compatibility stand-in)."""
175 """Returns None (ROS2 API compatibility stand-in)."""
180 """Returns None (ROS2 API compatibility stand-in)."""
185 """Returns None (ROS2 API compatibility stand-in)."""
190 raise AttributeError(
"handle cannot be modified after node creation")
193 """Returns the name of the node, without namespace."""
194 return rospy.get_name().rsplit(
"/", 1)[-1]
197 """Returns the namespace of the node."""
198 return "/" + rospy.get_namespace().strip(
"/")
201 """Returns `clock.Clock` using ROS time."""
205 """Get the node's logger."""
206 return ros1.get_logger()
208 def declare_parameter(self, name, value=None, descriptor=None, ignore_override=False):
210 Sets and initializes a node parameter.
212 This method,
if successful, will result
in any callback registered
with
213 `add_on_set_parameters_callback` to be called.
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
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
230 Sets a list of parameters.
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"
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.
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.
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
251 Parameters declared up to that point will
not be undeclared.
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
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
267 for index, parameter_tuple
in enumerate(parameters):
268 if len(parameter_tuple) < 1
or len(parameter_tuple) > 3:
270 'Invalid parameter tuple length at index {index} in parameters list: '
271 '{parameter_tuple}; expecting length between 1 and 3'.format_map(locals())
280 name = parameter_tuple[0]
282 isinstance(name, str), \
284 'First element {name} at index {index} in parameters list '
285 'is not a str.'.format_map(locals())
293 value = parameter_tuple[1]
296 descriptor = parameter_tuple[2]
298 isinstance(descriptor, ParameterDescriptor), \
300 'Third element {descriptor} at index {index} in parameters list '
301 'is not a ParameterDescriptor.'.format_map(locals())
303 except AssertionError
as assertion_error:
304 raise TypeError(assertion_error)
310 name =
"%s.%s" % (namespace, name)
312 parameter_list.append(
Parameter(name, value=value))
313 descriptors.update({name: descriptor})
315 parameters_already_declared = [
316 parameter.name
for parameter
in parameter_list
if parameter.name
in self.
_parameters
318 if any(parameters_already_declared):
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])
329 Unset a previously set parameter.
331 This method will not cause a callback registered
with
332 `add_on_set_parameters_callback` to be called.
334 @param name fully-qualified name of the parameter, including its namespace
336 @throws ParameterNotDeclaredException
if the parameter does
not exist
337 @throws ParameterImmutableException
if the parameter was created
as read-only
345 ros1.delete_param(name)
351 Returns whether parameter exists.
353 @param name fully-qualified name of the parameter, including its namespace
359 Returns a list of parameters.
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.
366 @throws ParameterNotDeclaredException
if undeclared parameters are
not allowed,
367 and any given parameter
is unknown
369 if not all(isinstance(name, str)
for name
in names):
370 raise TypeError(
'All names must be instances of type str')
375 Returns a parameter by name.
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.
382 @throws ParameterNotDeclaredException
if undeclared parameters are
not allowed,
383 and the parameter
is unknown
388 return Parameter(name, Parameter.Type.NOT_SET,
None)
394 Returns a parameter or the alternative value.
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.
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
403 if alternative_value
is None:
404 alternative_value =
Parameter(name, Parameter.Type.NOT_SET)
405 return self.
_parameters.get(name, alternative_value)
409 Get parameters that have a given prefix in their names
as a dictionary.
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
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.
421 @param prefix the prefix of the parameters to get
422 @return list of `Parameter` under the given prefix,
with prefix removed
from names
424 parameters_with_prefix = {}
426 prefix = prefix + PARAMETER_SEPARATOR_STRING
427 prefix_len = len(prefix)
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
436 Set parameters for the node,
and return the result
for the set action.
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.
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.
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.
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.
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.
458 @param parameter_list list of `Parameter` to set
459 @return list of `SetParametersResult`, one
for each input
461 @throws ParameterNotDeclaredException
if undeclared parameters are
not allowed,
462 and any given parameter
is unknown
466 def _set_parameters(self, parameter_list, descriptors=None, raise_on_failure=False,
467 allow_undeclared_parameters=False):
469 Set parameters for the node,
and return the result
for the set action.
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
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.
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
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
495 if descriptors
is not None:
496 assert all(parameter.name
in descriptors
for parameter
in parameter_list)
499 for param
in parameter_list:
500 if not allow_undeclared_parameters:
506 allow_not_set_type=allow_undeclared_parameters
508 if raise_on_failure
and not result.successful:
510 results.append(result)
515 Set the given parameters, all at one time, and then aggregate result.
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.
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.
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.
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.
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.
535 @param parameter_list list of `Parameter` to set
536 @return a single `SetParametersResult`
for all parameters
538 @throws ParameterNotDeclaredException
if undeclared parameters are
not allowed,
539 and any named parameter
is unknown
546 Check if all parameters
in list have correct types
and were declared beforehand.
548 @param parameter_list list of `Parameter` to check
549 @throws ParameterNotDeclaredException
if any given parameter
is unknown
551 if not all(isinstance(parameter, Parameter)
for parameter
in parameter_list):
552 raise TypeError(
"parameter must be instance of type '{}'".format(repr(Parameter)))
554 undeclared_parameters = (
555 param.name
for param
in parameter_list
if param.name
not in self.
_parameters
561 allow_not_set_type=False):
563 Set the given parameters, all at one time, and then aggregate result.
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.
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.
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
581 if descriptors
is not None:
584 assert all(parameter.name
in descriptors
for parameter
in parameter_list)
590 if not result.successful:
594 result = callback(parameter_list)
595 if not result.successful:
599 if result.successful:
600 for param
in parameter_list:
602 if not allow_not_set_type
and Parameter.Type.NOT_SET == param.type_:
609 ros1.delete_param(param.name)
614 if descriptors
is not None:
621 ros1.set_param(param.name, param.value)
627 Add a callback in front to the list of callbacks.
629 @param callback function to call
with (`[Parameter]`) when setting any node parameters,
630 returning `SetParametersResult`
636 Remove a callback from list of callbacks.
640 @throws ValueError
if the callback
is unknown
646 Apply descriptors to parameters and return an aggregated result without saving parameters.
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.
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
660 for param
in parameter_list:
661 if param.name
in descriptors:
663 if not result.successful:
669 Apply a descriptor to a parameter and return a result without saving the parameter.
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.
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
680 @throws ParameterNotDeclaredException
if descriptor
is not provided,
681 the given parameter
is unknown
682 and undeclared parameters are
not allowed
684 if descriptor
is None:
687 descriptor.name = parameter.name
690 descriptor.type = parameter.type_.value
692 if check_read_only
and descriptor.read_only:
695 reason=
'Trying to set a read-only parameter: {}.'.format(parameter.name))
697 if parameter.type_ == Parameter.Type.INTEGER
and descriptor.integer_range:
700 if parameter.type_ == Parameter.Type.DOUBLE
and descriptor.floating_point_range:
707 Returns whether parameter value passes integer range check.
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.
712 @param parameter `Parameter` to check
713 @param integer_range `IntegerRange` to use
714 @return `SetParametersResult`
with success
or failure reason
716 min_value = min(integer_range.from_value, integer_range.to_value)
717 max_value = max(integer_range.from_value, integer_range.to_value)
720 if parameter.value == min_value
or parameter.value == max_value:
723 if not min_value < parameter.value < max_value:
726 reason=
'Parameter {} out of range. '
727 'Min: {}, Max: {}, value: {}'.format(
728 parameter.name, min_value, max_value, parameter.value
732 if integer_range.step != 0
and (parameter.value - min_value) % integer_range.step != 0:
735 reason=
'The parameter value for {} is not a valid step. '
736 'Min: {}, max: {}, value: {}, step: {}'.format(
749 Returns whether parameter value passes floating-point range check.
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.
754 @param parameter `Parameter` to check
755 @param floating_point_range `FloatingPointRange` to use
756 @return `SetParametersResult`
with success
or failure reason
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)
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)
768 if not min_value < parameter.value < max_value:
771 reason=
'Parameter {} out of range '
772 'Min: {}, Max: {}, value: {}'.format(
773 parameter.name, min_value, max_value, parameter.value
777 if floating_point_range.step != 0.0:
778 distance_int_steps = round((parameter.value - min_value) / floating_point_range.step)
780 min_value + distance_int_steps * floating_point_range.step,
786 reason=
'The parameter value for {} is not close enough to a valid step. '
787 'Min: {}, max: {}, value: {}, step: {}'.format(
792 floating_point_range.step
800 Apply parameter descriptor and set parameter
if successful.
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
808 if result.successful:
814 Get the parameter descriptor of a given parameter.
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
821 @throws ParameterNotDeclaredException
if parameter
is unknown
822 and undeclared parameters are
not allowed
834 Get the parameter descriptors of a given list of parameters.
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.
841 @throws ParameterNotDeclaredException
if any parameter
is unknown
842 and undeclared parameters are
not allowed
844 parameter_descriptors = []
847 return parameter_descriptors
849 def set_descriptor(self, name, descriptor, alternative_value=None):
851 Set a new descriptor for a given parameter.
853 The name
in the descriptor
is ignored
and set to given `name`.
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
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
877 if alternative_value
is None:
878 alternative_parameter = current_parameter
880 alternative_parameter =
Parameter(name=name, value=alternative_value.get_value())
885 alternative_set_result = (
888 if not alternative_set_result.successful:
891 alternative_parameter.value,
892 alternative_set_result.reason
900 Register a set parameters callback.
904 Calling this function will add a callback to the self._parameter_callbacks list.
906 @param callback function to call
with `([`Parameter`])` when setting any node parameters,
907 returning `SetParametersResult`
910 'set_parameters_callback() is deprecated. '
911 'Use add_on_set_parameters_callback() instead'
916 """Does nothing (ROS2 API compatibility stand-in)."""
919 """Does nothing (ROS2 API compatibility stand-in)."""
922 *, callback_group=None, event_callbacks=None):
924 Creates a new publisher.
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
934 queue_size = qos_profile if isinstance(qos_profile, int)
else qos_profile.depth
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)
943 *, callback_group=None, event_callbacks=None, raw=False):
945 Creates a new subscription.
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
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)
964 def create_client(self, srv_type, srv_name, *, qos_profile=None, callback_group=None):
966 Creates a new service client.
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
974 client = ros1.create_client(srv_name, srv_type)
979 *, qos_profile=None, callback_group=None):
981 Creates a new service server.
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
991 service = ros1.create_service(srv_name, srv_type, callback)
995 def create_timer(self, timer_period_sec, callback, callback_group=None, clock=None):
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
1008 timer = ros1.create_timer(timer_period_sec, callback)
1009 timer._clock = clock or self.
_clock
1014 """Does nothing and returns None (ROS2 API compatibility stand-in)."""
1019 Creates a rate object.
1021 The timer will be started and every `timer_period_sec` number of seconds the provided
1022 callback function will be called.
1024 @param frequency the frequency the Rate runs at (Hz)
1025 @param clock ignored (ROS2 API compatibility stand-
in)
1026 @return `rospy.Rate` instance
1029 raise ValueError(
'frequency must be > 0')
1030 return ros1.create_rate(frequency)
1034 Destroy a publisher created by the node.
1036 @return `
True`
if successful, `
False` otherwise
1038 publisher.unregister()
1046 Destroy a subscription created by the node.
1048 @return `
True`
if successful, `
False` otherwise
1050 subscription.unregister()
1058 Destroy a service client created by the node.
1060 @return `
True`
if successful, `
False` otherwise
1070 Destroy a service server created by the node.
1072 @return `
True`
if successful, `
False` otherwise
1082 Destroy a timer created by the node.
1084 @return `
True`
if successful, `
False` otherwise
1093 Does nothing (ROS2 API compatibility stand-in).
1101 Does nothing (ROS2 API compatibility stand-in).
1109 Destroys the node and shuts down rospy.
1111 Frees resources used by the node, including any entities created by the following methods:
1113 * `create_publisher`
1114 * `create_subscription`
1130 rospy.signal_shutdown(reason=
"")
1134 Gets a list of discovered topics for publishers of a remote node.
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
1142 @throws NodeNameNonExistentError
if the node wasn
't found
1143 @throws RuntimeError unexpected failure
1146 node_name = util.namejoin(node_namespace, node_name)
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())
1166 Gets a list of discovered topics for subscriptions of a remote node.
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
1174 @throws NodeNameNonExistentError
if the node wasn
't found
1175 @throws RuntimeError unexpected failure
1178 node_name = util.namejoin(node_namespace, node_name)
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())
1198 Gets a list of discovered service server topics for a remote node.
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
1206 @throws NodeNameNonExistentError
if the node wasn
't found
1207 @throws RuntimeError unexpected failure
1210 node_name = util.namejoin(node_namespace, node_name)
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())
1227 Returns an empty list (ROS2 API compatibility stand-in)
1229 ROS1 does
not provide service clients information.
1231 @param node_name ignored
1232 @param node_namespace ignored
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
1245 return ros1.get_topics()
1249 Gets a list of available services.
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
1254 return ros1.get_services()
1258 Get a list of names for discovered nodes.
1260 @return list of node names without namespaces
1262 return [util.namesplit(n)[-1]
for n
in ros1.get_nodes()]
1266 Get a list of names and namespaces
for discovered nodes.
1268 @return list of tuples containing two strings: the node name
and node namespace
1270 return [util.namesplit(n)[::-1]
for n
in ros1.get_nodes()]
1274 Get a list of names, namespaces and enclaves
for discovered nodes.
1276 @return list of tuples containing three strings: the node name, node namespace
1277 and enclave (the latter always
"/" in ROS1)
1279 return [util.namesplit(n)[::-1] + (
"/", )
for n
in ros1.get_nodes()]
1283 Return the number of publishers on a given topic, globally.
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.
1289 @param topic_name the topic_name on which to count the number of publishers
1290 @return the number of publishers on the topic
1292 topic_name = ros1.resolve_name(topic_name)
1294 nodes = sum((nn
for t, nn
in ros1.MASTER.getSystemState()[-1][0]
if t == topic_name), [])
1299 Return the number of subscribers on a given topic.
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.
1305 @param topic_name the topic_name on which to count the number of subscribers
1306 @return the number of subscribers on the topic
1308 topic_name = ros1.resolve_name(topic_name)
1310 nodes = sum((nn
for t, nn
in ros1.MASTER.getSystemState()[-1][1]
if t == topic_name), [])
1315 Returns a list of `TopicEndpointInfo`.
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
1323 topic_name = ros1.remap_name(ros1.resolve_name(topic_name))
1324 IDX = 0
if TopicEndpointTypeEnum.PUBLISHER == endpoint_type
else 1
1327 nodes = sum((nn
for t, nn
in ros1.MASTER.getSystemState()[-1][IDX]
if t == topic_name), [])
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)
1339 Return a list of publishers on a given topic.
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.
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.
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
1354 return self.
_get_info_by_topic(topic_name, TopicEndpointTypeEnum.PUBLISHER, no_mangle)
1358 Return a list of subscriptions on a given topic.
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.
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.
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.
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
1378 return self.
_get_info_by_topic(topic_name, TopicEndpointTypeEnum.SUBSCRIPTION, no_mangle)
1382 "PARAMETER_SEPARATOR_STRING",
"FloatingPointRange",
"IntegerRange",
1383 "NodeNameNonExistentError",
"Node",
"Parameter",
"ParameterDescriptor",
"ParameterValue",
1384 "SetParametersResult"
Simple clock interface mimicking `rclpy.clock.Clock`, only providing `now()`.
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.
count_subscribers(self, topic_name)
Return the number of subscribers on a given topic.
get_client_names_and_types_by_node(self, node_name, node_namespace)
Returns an empty list (ROS2 API compatibility stand-in)
destroy_client(self, client)
Destroy a service client created by the node.
set_parameters_atomically(self, parameter_list)
Set the given parameters, all at one time, and then aggregate result.
__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.
remove_on_set_parameters_callback(self, callback)
Remove a callback from list of callbacks.
_apply_descriptor_and_set(self, parameter, descriptor=None, check_read_only=True)
Apply parameter descriptor and set parameter if successful.
waitables
Yields (ROS2 API compatibility stand-in).
guards
Yields (ROS2 API compatibility stand-in).
_apply_descriptor(self, parameter, descriptor=None, check_read_only=True)
Apply a descriptor to a parameter and return a result without saving the parameter.
_check_undeclared_parameters(self, parameter_list)
Check if all parameters in list have correct types and were declared beforehand.
undeclare_parameter(self, name)
Unset a previously set parameter.
_apply_descriptors(self, parameter_list, descriptors, check_read_only=True)
Apply descriptors to parameters and return an aggregated result without saving parameters.
destroy_subscription(self, subscription)
Destroy a subscription created by the node.
create_service(self, srv_type, srv_name, callback, *qos_profile=None, callback_group=None)
Creates a new service server.
get_service_names_and_types_by_node(self, node_name, node_namespace)
Gets a list of discovered service server topics for a remote node.
has_parameter(self, name)
Returns whether parameter exists.
context
Returns None (ROS2 API compatibility stand-in).
get_parameters_by_prefix(self, prefix)
Get parameters that have a given prefix in their names as a dictionary.
set_parameters(self, parameter_list)
Set parameters for the node, and return the result for the set action.
destroy_service(self, service)
Destroy a service server created by the node.
set_parameters_callback(self, callback)
Register a set parameters callback.
describe_parameters(self, names)
Get the parameter descriptors of a given list of parameters.
subscriptions
Yields subscriptions that have been created on this node.
destroy_publisher(self, publisher)
Destroy a publisher created by the node.
create_publisher(self, msg_type, topic, qos_profile, *callback_group=None, event_callbacks=None)
Creates a new publisher.
handle
Returns None (ROS2 API compatibility stand-in).
create_timer(self, timer_period_sec, callback, callback_group=None, clock=None)
Creates a new timer.
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.
executor
Returns None (ROS2 API compatibility stand-in).
services
Yields services that have been created on this node.
_apply_integer_range(self, parameter, integer_range)
Returns whether parameter value passes integer range check.
destroy_guard_condition(self, guard)
Does nothing (ROS2 API compatibility stand-in).
add_waitable(self, waitable)
Does nothing (ROS2 API compatibility stand-in).
_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.
create_guard_condition(self, callback, callback_group=None)
Does nothing and returns None (ROS2 API compatibility stand-in).
create_client(self, srv_type, srv_name, *qos_profile=None, callback_group=None)
Creates a new service client.
clients
Yields clients that have been created on this node.
destroy_timer(self, timer)
Destroy a timer created by the node.
_allow_undeclared_parameters
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.
get_clock(self)
Returns `clock.Clock` using ROS time.
get_publishers_info_by_topic(self, topic_name, no_mangle=False)
Return a list of publishers on a given topic.
get_service_names_and_types(self)
Gets a list of available services.
get_node_names(self)
Get a list of names for discovered nodes.
remove_waitable(self, waitable)
Does nothing (ROS2 API compatibility stand-in).
count_publishers(self, topic_name)
Return the number of publishers on a given topic, globally.
destroy_rate(self, rate)
Does nothing (ROS2 API compatibility stand-in).
int PARAM_REL_TOL
Relative tolerance for floating-point parameter range steps.
declare_parameters(self, namespace, parameters, ignore_override=False)
Sets a list of parameters.
create_subscription(self, msg_type, topic, callback, qos_profile, *callback_group=None, event_callbacks=None, raw=False)
Creates a new subscription.
get_parameters(self, names)
Returns a list of parameters.
declare_parameter(self, name, value=None, descriptor=None, ignore_override=False)
Sets and initializes a node parameter.
get_parameter(self, name)
Returns a parameter by name.
describe_parameter(self, name)
Get the parameter descriptor of a given parameter.
create_rate(self, frequency, clock=None)
Creates a rate object.
get_node_names_and_namespaces(self)
Get a list of names and namespaces for discovered nodes.
timers
Yields timers that have been created on this node.
publishers
Yields publishers that have been created on this node.
_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.
_get_info_by_topic(self, topic_name, endpoint_type, no_mangle)
Returns a list of `TopicEndpointInfo`.
destroy_node(self)
Destroys the node and shuts down rospy.
add_on_set_parameters_callback(self, callback)
Add a callback in front to the list of callbacks.
_apply_floating_point_range(self, parameter, floating_point_range)
Returns whether parameter value passes floating-point range check.
get_topic_names_and_types(self, no_demangle=False)
Gets a list of available topic names and types.
get_parameter_or(self, name, alternative_value=None)
Returns a parameter or the alternative value.
default_callback_group
Returns None (ROS2 API compatibility stand-in).
get_node_names_and_namespaces_with_enclaves(self)
Get a list of names, namespaces and enclaves for discovered nodes.
set_descriptor(self, name, descriptor, alternative_value=None)
Set a new descriptor for a given parameter.
get_subscriptions_info_by_topic(self, topic_name, no_mangle=False)
Return a list of subscriptions on a given topic.
Thrown when a node name is not found.
This is the message to communicate a parameter's descriptor.
ROS node parameter, a stand-in for ROS2 `rclpy.parameter.Parameter` in ROS1.
This is the message to communicate the result of setting parameters.
Information on a topic endpoint.
get_logger()
Returns `logging.Logger` for logging to ROS log handler.
get_namespace()
Returns ROS node namespace.
shutdown(*context=None)
Sends the shutdown signal to rospy.