# embedding_metadata

key: chroma:document
string_value:
in mind,ros2doctoris not a debug tool; it won’t help with errors in your code or on the implementation side of your system.Related contentros2doctor’s READMEwill tell you more about different arguments. You might want to take a look around theros2doctorrepo as well, since it’s fairly beginner friendly and a great place to get started with contributing.Next stepsYou’ve completed the beginner level tutorials!


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 doctor

Language: unknown

All <n> checks passed

Language: unknown

<path>: <line>: UserWarning: <message>

Language: unknown UserWarning: Distribution <distro> is not fully supported or tested. To get more consistent features, download a stable version at https://index.ros.org/doc/ros2/Installation/

Language: unknown 1/3 checks failedFailed modules:  network

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtle_teleop_key

Language: unknown UserWarning: Publisher without subscriber detected on /turtle1/color_sensor.UserWarning: Publisher without subscriber detected on /turtle1/pose.

Language: unknown

ros2 topic echo /turtle1/color_sensor

Language: unknown

ros2 topic echo /turtle1/pose

Language: unknown

ros2 doctor -

report

Language: unknown NETWORK CONFIGURATION...PLATFORM INFORMATION...RMW MIDDLEWARE...ROS 2 INFORMATION...TOPIC LIST...


key: chroma:document
string_value:
Language: unknown distribution name      : <distro>distribution type      : ros2distribution status    : prereleaserelease platforms      : {'<platform>': ['<version>']}


key: chroma:document
string_value:
Title: Humble Hawksbill (humble)

URL: https://docs.ros.org/en/jazzy/Releases/Release

Humble

Hawksbill.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Humble Hawksbill (humble)Table of ContentsSupported PlatformsInstallationChanges in Patch Release 1 (2022-11-23)ros2topicNew features in this ROS 2 releaseament_cmake_gen_version_hlaunchlaunch_rosSROS2 Security enclaves support Certificate Revocation ListsContent Filtered Topicsros2clirviz2Changes since the Galactic releaseC++ headers are installed in a subdirectorycommon_interfacesrmwrmw_connextddsrclrclcpprclcpp_lifecyclerclpyros1_bridgeros2clirobot_state_publisherrosidl_cmakerviz2geometry2rosbag2Known IssuesRelease TimelineHumble Hawksbillis the eighth release of ROS 2. What follows is highlights of the important changes and features in Humble Hawksbill since the last release. For a list of all of the changes since Galactic, see thelong form changelog.Supported PlatformsHumble Hawksbill is primarily supported on the following platforms:Tier 1 platforms:Ubuntu 22.04 (Jammy):amd64andarm64Windows 10 (Visual Studio 2019):amd64Tier 2 platforms:RHEL 8:amd64Tier 3 platforms:Ubuntu 20.04


key: chroma:document
string_value:
2 platforms:RHEL 8:amd64Tier 3 platforms:Ubuntu 20.04 (Focal):amd64macOS:amd64Debian Bullseye:amd64For more information about RMW implementations, compiler / interpreter versions, and system dependency versions seeREP 2000.InstallationInstall Humble HawksbillChanges in Patch Release 1 (2022-11-23)ros2topicnowas keyword forbuiltin_interfaces.msg.Timeandautoforstd_msgs.msg.Headerros2topicpubnow allows to set abuiltin_interfaces.msg.Timemessage to the current time via thenowkeyword. Similarly, astd_msg.msg.Headermessage will be automatically generated when passed the keywordauto. This behavior matches that of ROS 1’srostopic(http://wiki.ros.org/ROS/YAMLCommandLine#Headers.2Ftimestamps)Related PR:ros2/ros2cli#751New features in this ROS 2 releaseament_cmake_gen_version_hGenerating a C/C++ header with version infoA new CMake function to generate a header with the package version info was added to theament_cmake_gen_version_hinament/ament_cmake#377. Here’s the simplest use


key: chroma:document
string_value:
Here’s the simplest use case:project(my_project)add_library(my_lib...)ament_generate_version_header(my_lib)It will generate a header with version info from thepackage.xmland make it available to targets that link against themy_liblibrary.How to include the header:#include<my_project/version.h>Where the header is installed to:set(VERSION_HEADER${CMAKE_INSTALL_PREFIX}/include/my_project/my_project/version.h)launchScoping environment variables in group actionsSimilar to launch configurations, now by default, the state of environment variables are scoped to group actions.For example, in the following launch files the executed processe will echo the value1(before Humble it would echo2):XMLPython<launch><set_envname="FOO"value="1"/><group><set_envname="FOO"value="2"/></group><executablecmd="echo


key: chroma:document
string_value:
$FOO"output="screen"shell="true"/></launch>importlaunchimportlaunch.actionsdefgenerate_launch_description():returnlaunch.LaunchDescription([launch.actions.SetEnvironmentVariable(name='FOO',value='1'),launch.actions.GroupAction([launch.actions.SetEnvironmentVariable(name='FOO',value='2'),]),launch.actions.ExecuteProcess(cmd=['echo','$FOO'],output='screen',shell=True),])If you would like disable scoping for launch configurations and and environment variables you can set thescopedargument (or attribute) to false.Related PR:ros2/launch#601launch_pytestWe’ve added a new package,launch_pytest, that acts as an alternative tolaunch_testing.launch_pytestis a simple pytest plugin that provides pytest fixtures to manage the lifetime of a launch service.Check out thepackage README for details and examples.Related PR:ros2/launch#528Allow matching target actions with a callableEvent handlers that take a target action object to match can now also take a callable instead to do the matching.Related PR:ros2/launch#540Access


key: chroma:document
string_value:
instead to do the matching.Related PR:ros2/launch#540Access to math module when evaluating Python expressionsInsidePythonExpressionsubstitutions (eval) we can now use symbols from Python’s math module. For example,<launch><logmessage="$(eval 'ceil(pi)')"/></launch>Related PR:ros2/launch#557Boolean substitutionsNew substitutionsNotSubstitution,AndSubstitution, andOrSubstitutionprovide a convenient way to perform logical operations, for example<launch><letname="p"value="true"/><letname="q"value="false"/><groupif="$(or $(var p) $(var q))"><logmessage="The first condition is true"/></group><groupunless="$(and $(var p) $(var q))"><logmessage="The second condition is false"/></group><groupif="$(not $(var q))"><logmessage="The third condition is true"/></group></launch>Related PR:ros2/launch#598New actionsAppendEnvironmentVariableappends a value to an existing environment variable.Related PR:ros2/launch#543ResetLaunchConfigurationsresets any configuration applied to the launch configuration.Related


key: chroma:document
string_value:
any configuration applied to the launch configuration.Related PR:ros2/launch#515launch_rosPassing ROS arguments to node actionsIt is now possible to provideROS-specific node argumentsdirectly, without needing to useargswith a leading--ros-argsflag:XMLYAML<launch><nodepkg="demo_nodes_cpp"exec="talker"ros_args="--log-level debug"/></launch>launch:-node:pkg:demo_nodes_cppexec:talkerros_args:'--log-leveldebug'The corresponding parameter for theNodeaction in Python launch files isros_arguments:fromlaunchimportLaunchDescriptionimportlaunch_ros.actionsdefgenerate_launch_description():returnLaunchDescription([launch_ros.actions.Node(package='demo_nodes_cpp',executable='talker',ros_arguments=['--log-level','debug'],),])Related PRs:ros2/launch_ros#249andros2/launch_ros#253.Frontend support for composable nodesWe can now start node containers and load components into them from frontend launch files, for


key: chroma:document
string_value:
and load components into them from frontend launch files, for example:XMLYAML<launch><node_containerpkg="rclcpp_components"exec="component_container"name="my_container"namespace=""><composable_nodepkg="composition"plugin="composition::Talker"name="talker"/></node_container><load_composable_nodetarget="my_container"><composable_nodepkg="composition"plugin="composition::Listener"name="listener"/></load_composable_node></launch>launch:-node_container:pkg:rclcpp_componentsexec:component_containername:my_containernamespace:''composable_node:-pkg:compositionplugin:composition::Talkername:talker-load_composable_node:target:my_containercomposable_node:-pkg:compositionplugin:composition::Listenername:listenerRelated PR:ros2/launch_ros#235Parameter substitutionThe newParameterSubstitutionlets you substitute the value of a parameter set previously in launch with theSetParameteraction. For example,<launch><set_parametername="foo"value="bar"/><logmessage="Parameter foo has value $(param foo)"/></launch>Related


key: chroma:document
string_value:
foo has value $(param foo)"/></launch>Related PR:ros2/launch_ros#297New actionsRosTimeracts like the launchTimerAction, but uses a ROS clock (so it can use simulation time, for example).Related PRs:ros2/launch_ros#244andros2/launch_ros#264SetParametersFromFilepasses a ROS parameters file to all nodes in a launch file (including node components).Related PRs:ros2/launch_ros#260andros2/launch_ros#281SROS2 Security enclaves support Certificate Revocation ListsCertificate Revocation Lists (CRLs) are a concept where particular certificates can be revoked before their expiration. As of Humble, it is now possible to put a CRL in an SROS2 security enclave and have it be honored. Seethe SROS2 tutorialsfor an example of how to use it.Content Filtered TopicsContent Filtered Topics supports a more sophisticated subscription that indicates the subscriber does not want to necessarily see all values of each instance published under the Topic. Content Filtered Topics can be used to request content-based subscriptions when


key: chroma:document
string_value:
Topics can be used to request content-based subscriptions when underlying RMW implementation supports this feature.RMW Content Filtered Topics supportrmw_fastrtpssupportedrmw_connextddssupportedrmw_cycloneddsnot supportedTo learn more, see thecontent_filteringexamples.Related design PR:ros2/design#282.ros2cliros2launchhas a--launch-prefixargumentThis allows passing a prefix to all executables in a launch file, which is useful in many debugging situations. See the associatedpull request, as well as thetutorialfor more information.Relatedly, the--launch-prefix-filtercommand-line option was added to selectively add the prefix from--launch-prefixto executables. See thepull requestfor more information.ros2topicechohas a--flow-styleargumentThis allows the user to forceflowstylefor the YAML representation of data on a topic. Without this option, the output fromros2topicecho/tf_staticcould look something


key: chroma:document
string_value:
the output fromros2topicecho/tf_staticcould look something like:transforms:-header:stamp:sec:1651172841nanosec:433705575frame_id:single_rrbot_link3child_frame_id:single_rrbot_camera_linktransform:translation:x:0.05y:0.0z:0.9rotation:x:0.0y:0.0z:0.0w:1.0With this option, the output would look something like:transforms:[{header:{stamp:{sec:1651172841,nanosec:433705575},frame_id:single_rrbot_link3},child_frame_id:single_rrbot_camera_link,transform:{translation:{x:0.05,y:0.0,z:0.9},rotation:{x:0.0,y:0.0,z:0.0,w:1.0}}}]See thePyYAML documentationfor more information.ros2topicechocan filter data based on message contentsThis allows the user to only print out data on a topic that matches a certain Python expression. For instance, using the following argument will only print out string messages that start with ‘foo’:ros2topicecho--filter'm.data.startswith("foo")` /chatterSee thepull requestfor more information.rviz2Apply textures to arbitrary triangle listsWe’ve addedthe ability to apply textures defined via URI


key: chroma:document
string_value:
listsWe’ve addedthe ability to apply textures defined via URI to arbitrary triangle lists using UV Coordinates. Now we can create a gradient pull from a texture map instead of the default grayscale. This will enable complex coloring of markers. To use this, you should use thevisualization_msgs/Marker.msgand fill thetexture_resource,texture,uv_coordinatesandmesh_filefields. You can find more informationhere.Visualization of mass properties (including inertia)We also added the ability to visualize inertias. To do this, you select enable ‘Inertia’ in the ‘Mass Properties’ under the robot model:You can see an image of an inertia below.Visualize YUV images in RVizIt is now possible to directly visualize YUV images inside of RViz, rather than having to convert to RGB first. Seeros2/rviz#701for details.Allow rendering of objects > 100 metersBy default, RViz only renders objects that are within 100 meters of a camera. A new configuration property called “Far Plane Distance” in the rviz camera plugin allows that


key: chroma:document
string_value:
“Far Plane Distance” in the rviz camera plugin allows that rendering distance to be configured.Seeros2/rviz#849for more information.Changes since the Galactic releaseC++ headers are installed in a subdirectoryIn ROS 2 releases prior to Humble, C++ headers for all packages were installed into a single include directory. For instance, in Galactic, the directory structure looks like this (reduced for brevity):/opt/ros/galactic/include/ ├── rcl │   ├── node.h ├── rclcpp │   ├── node.hppThis structure can cause serious problems when trying to use overlays. That is, it is very possible to get the wrong set of header files due to include directory order. Seehttps://colcon.readthedocs.io/en/released/user/overriding-packages.htmlfor a detailed explanation of the problems.To help combat this, in Humble (and in all ROS 2 releases going forward), the directory structure has changed:/opt/ros/humble/include ├── rcl │   └── rcl │       ├── node.h ├── rclcpp │   └── rclcpp │       ├── node.hppNote that downstream packages


key: chroma:document
string_value:
└── rclcpp │       ├── node.hppNote that downstream packages that use these headers donothave to change; using#include<rclcpp/node.hpp>works as it always did before. However, when using IDEs that are looking for include directories, it may be necessary to add the individual include directories to the search path.Seehttps://github.com/ros2/ros2/issues/1150for more information, including the reasoning behind this change.common_interfacesSupport Textures and Embedded Meshes for Marker MessagesThese two additions will improve the ability to both visualize data in new ways with standard messages and, simultaneously, enable the ability to track this data in rosbag.Texturesbring the addition of three new fields to markers:# Texture resource is a special URI that can either reference a texture file in# a format acceptable to (resource retriever)[https://index.ros.org/p/resource_retriever/]# or an embedded texture via a string matching the format:#   "embedded://texture_name"stringtexture_resource# An image to be


key: chroma:document
string_value:
"embedded://texture_name"stringtexture_resource# An image to be loaded into the rendering engine as the texture for this marker.# This will be used iff texture_resource is set to embedded.sensor_msgs/CompressedImagetexture# Location of each vertex within the texture; in the range: [0.0-1.0]UVCoordinate[]uv_coordinatesRViz will fully support texture rendering through the embedded format.To those familiar withmesh_resource,resource_retrievershould be familiar. This will allow the programmer to choose where they want to load data from, either a local file or a networked file. In the interest of being able to record all data in a rosbag, the ability to embed the texture image is included.Mesheswere modified in a similar way to add the ability to embed a raw Mesh file for the purpose of recording and are modified in a similar way. The Meshfile message has two fields:# The filename is used for both debug purposes and to provide a file extension# for whatever parser is used.stringfilename# This stores the raw text


key: chroma:document
string_value:
parser is used.stringfilename# This stores the raw text of the mesh file.uint8[]dataThe embeddedMeshfilemessage is not yet supported in implementation.Related PRs:ros2/common_interfaces#153ros2/rviz#719AddedPRISMtype to SolidPrimitiveTheSolidPrimitivemessage had a newPRISMtype added, along with the appropriate metadata. Seeros2/common_interfaces#167for more information.rmwstructtype name suffix changed from_tto_sTo avoid type name duplication errors betweenstructtype names and theirtypedef-ed aliases when generating code documentation, the suffix for allstructtype names has been changed from_tto_s. Aliases with_tsuffixes remain in place. Thus, this change is a breaking change only for code that uses fullstructtype specifiers i.e.structtype_name_t.Seeros2/rmw#313for more details.rmw_connextddsUse Connext 6 by defaultBy default, Humble Hawksbill uses Connext 6.0.1 as the DDS implementation forrmw_connextdds. It is still possible to use Connext 5.3.1 withrmw_connextdds, but it must be rebuilt from


key: chroma:document
string_value:
Connext 5.3.1 withrmw_connextdds, but it must be rebuilt from source.rclstructtype name suffix changed from_tto_sTo avoid type name duplication errors betweenstructtype names and theirtypedef-ed aliases when generating code documentation, the suffix for allstructtype names has been changed from_tto_s. Aliases with_tsuffixes remain in place. Thus, this change is a breaking change only for code that uses fullstructtype specifiers i.e.structtype_name_t.Seeros2/rcl#932for more details.ROS_DISABLE_LOANED_MESSAGES environment variable addedThis environment variable can be used to disable loaned messages support, independently if the rmw supports them or not. For more details, see the guideConfigure Zero Copy Loaned Messages.rclcppSupport Type Adaption for Publishers and SubscriptionsAfter defining a type adapter, custom data structures can be used directly by publishers and subscribers, which helps to avoid additional work for the programmer and potential sources of errors. This is especially useful when


key: chroma:document
string_value:
and potential sources of errors. This is especially useful when working with complex data types, such as when converting OpenCV’scv::Matto ROS’ssensor_msgs/msg/Imagetype.Here is an example of a type adapter that convertsstd_msgs::msg::Stringtostd::string:template<>structrclcpp::TypeAdapter<std::string,std_msgs::msg::String>{usingis_specialized=std::true_type;usingcustom_type=std::string;usingros_message_type=std_msgs::msg::String;staticvoidconvert_to_ros_message(constcustom_type&source,ros_message_type&destination){destination.data=source;}staticvoidconvert_to_custom(constros_message_type&source,custom_type&destination){destination=source.data;}};And an example of how the type adapter can be used:usingMyAdaptedType=TypeAdapter<std::string,std_msgs::msg::String>;// Publish a std::stringautopub=node->create_publisher<MyAdaptedType>(...);std::stringcustom_msg="My std::string"pub->publish(custom_msg);// Pass a std::string to a subscription's


key: chroma:document
string_value:
Pass a std::string to a subscription's callbackautosub=node->create_subscription<MyAdaptedType>("topic",10,[](conststd::string&msg){...});To learn more, see thepublisherandsubscriptionexamples, as well as a more complexdemo. For more details, seeREP 2007.Client::asnyc_send_request(request)returns astd::futureinstead of astd::shared_futureThis change was implemented inrclcpp#1734. This breaks API, asstd::future::get()methods extracts the value from the future. That means, if that method is called for a second time it will throw an exception. That doesn’t happen with astd::shared_future, as itsget()method returns aconst&. Example:autofuture=client->async_send_request(req);...do_something_with_response(future.get());...do_something_else_with_response(future.get());// this will throw an exception now!!should be updated to:autofuture=client->async_send_request(req);...autoresponse=future.get();do_something_with_response(response);...do_something_else_with_response(response);If a shared future is needed,


key: chroma:document
string_value:
a shared future is needed, thestd::future::share()method can be used.wait_for_all_ackedmethod added toPublisherThis new method will block until all messages in the publisher queue are acked by the matching subscriptions or the specified timeout expires. It is only useful for reliable publishers, as in the case of best effort QoS there’s no acking. Examples:autopub=node->create_publisher<std_msgs::msg::String>(...);...pub->publish(my_msg);...pub->wait_for_all_acked();// or pub->wait_for_all_acked(timeout)For a more complete example, seehere.get_callback_groupsmethod removed fromNodeBaseandNodeclassesfor_each_callback_group()method has replacedget_callback_groups()by providing a thread-safe way to accesscallback_groups_vector.for_each_callback_group()accepts a function as an argument, iterates over the stored callback groups, and calls the passed function to ones that are valid.For more details, please refer to thispull request.add_to_wait_setmethod fromWaitableclass changes its return type


key: chroma:document
string_value:
fromWaitableclass changes its return type frombooltovoidBefore, classes derived fromWaitableoverridingadd_to_wait_setwere returning false when failing to add elements to the wait set, so the caller had to check this return value and throw or handle the error. This error handling should now be done directly onadd_to_wait_setmethod, throwing if necessary. It is not required to return anything if no errors happened. Thus, this is a breaking change for downstream uses ofWaitable.Seeros2/rclcpp#1612for more details.get_notify_guard_conditionmethod return type fromNodeBaseInterfaceclass changedNowrclcppuses theGuardConditionclass wrapper aroundrcl_guard_condition_t, soget_notify_guard_conditionreturns a reference to the node’srclcpp::GuardCondition. Thus, this is a breaking change for downstream uses ofNodeBaseInterfaceandNodeBase.Seeros2/rclcpp#1612for more details.sleep_untilandsleep_formethods added toClockTwo new methods were added to allow sleeping on a particular clock


key: chroma:document
string_value:
new methods were added to allow sleeping on a particular clock inros2/rclcpp#1814andros2/rclcpp#1828.Clock::sleep_untilwill suspend the current thread until the clock reaches a particular time.Clock::sleep_forwill suspend the current thread until the clock advances a certain amount of time from when the method was called. Both methods will wake early if theContextis shutdown.rclcpp_lifecycleActive and deactivate transitions of publishers will be triggered automaticallyBefore, users needed to overrideLifecylceNode::on_activate()andLifecylceNode::on_deactivate()and call the similarly named methods onLifecyclePublisherto make the transition actually happen. Now,LifecylceNodeprovides a default interface of these methods that already do this. See the implementation of thelifecycle_talkernodehere.rclpyManaged nodesLifecycle nodes support was added to rclpy. A complete demo can be foundhere.wait_for_all_ackedmethod added toPublisherSimilar to the feature added to rclcpp.sleep_untilandsleep_formethods added


key: chroma:document
string_value:
feature added to rclcpp.sleep_untilandsleep_formethods added toClockTwo new methods were added to allow sleeping on a particular clock inros2/rclpy#858andros2/rclpy#864.sleep_untilwill suspend the current thread until the clock reaches a particular time.sleep_forwill suspend the current thread until the clock advances a certain amount of time from when the method was called. Both methods will wake early if theContextis shutdown.ros1_bridgeSince there is no official ROS 1 distribution on Ubuntu Jammy and forward,ros1_bridgeis now compatible with the Ubuntu-packaged versions of ROS 1. More details about usingros1_bridgewith Jammy packages are available inthe how-to guides.ros2cliros2commands disable output buffering by defaultPrior to this release, running a command likeros2echo/chatter|grep"Hello"would not print any data until the output buffer was full. Users could work around this by settingPYTHONUNBUFFERED=1, but that was not very user friendly.Instead, allros2commands now do line-buffering by default,


key: chroma:document
string_value:
allros2commands now do line-buffering by default, so commands like the above work as soon as a newline is printed. To disable this behavior and use default python buffering rules, use the option--use-python-default-buffering. See theoriginal issueand thepull requestfor more information.ros2topicpubwill wait for one matching subscription when using--times/--once/-1When using--times/--once/-1flags,ros2topicpubwill wait for one matching subscription to be found before starting to publish. This avoids the issue of the ros2cli node starting to publish before discovering a matching subscription, which results in some of the first messages being lost. This is particularly unexpected when using a reliable qos profile.The number of matching subscriptions to wait before starting publishing can be configured with the-w/--wait-matching-subscriptionsflags, e.g.:ros2 topic pub -1 -w 3 /chatter std_msgs/msg/String "{data: 'foo'}"to wait for three matching subscriptions before starting to publish.-wcan also be used


key: chroma:document
string_value:
subscriptions before starting to publish.-wcan also be used independently of--times/--once/-1but it only defaults to one when combined with them, otherwise the-wdefault is zero.Seehttps://github.com/ros2/ros2cli/pull/642for more details.ros2paramdumpdefault output changed--printoption for dump command wasdeprecated.It prints to stdout by default:ros2paramdump/my_node_name--output-diroption for dump command wasdeprecated.To dump parameters to a file, run:ros2paramdump/my_node_name>my_node_name.yamlros2paramsetnow accepts more YAML syntaxPreviously, attempting to set a string like “off” to a parameter that was of string type did not work. That’s becauseros2paramsetinterprets the command-line arguments as YAML, and YAML considers “off” to be a boolean type. As ofhttps://github.com/ros2/ros2cli/pull/684,ros2paramsetnow accepts the YAML escape sequence of “!!str off” to ensure that the value is considered a string.ros2pkgcreatecan automatically generate a LICENSE fileIf the--licenseflag is passed


key: chroma:document
string_value:
generate a LICENSE fileIf the--licenseflag is passed toros2pkgcreate, and the license is one of the known licenses,ros2pkgcreatewill now automatically generate a LICENSE file in the root of the package. For a list of known licenses, runros2pkgcreate--license?<package_name>. See the associatedpull requestfor more information.robot_state_publisherAddedframe_prefixparameterA new parameterframe_prefixwas added inros/robot_state_publisher#159. This parameter is a string which is prepended to all frame names published byrobot_state_publisher. Similar totf_prefixin the originaltflibrary in ROS 1, this parameter can be used to publish the same robot description multiple times with different frame names.Removal of deprecateduse_tf_staticparameterThe deprecateduse_tf_staticparameter has been removed fromrobot_state_publisher. This means that static transforms are unconditionally published to the/tf_statictopic, and that the static transforms are published in atransient_localQuality of Service. This was the default


key: chroma:document
string_value:
in atransient_localQuality of Service. This was the default behavior, and the behavior which thetf2_ros::TransformListenerclass expected before, so most code will not have to be changed. Any code that was relying onrobot_state_publisherto periodically publish static transforms to/tfwill have to be updated to subscribe to/tf_staticas atransient_localsubscription instead.rosidl_cmakeDeprecation ofrosidl_target_interfaces()The CMake functionrosidl_target_interfaces()has been deprecated, and now issues a CMake warning when called. Users wanting to use messages/services/actions in the same ROS package that generated them should instead callrosidl_get_typesupport_target()and thentarget_link_libraries()to make their targets depend on the returned typesupport target. Seehttps://github.com/ros2/rosidl/pull/606for more details, andhttps://github.com/ros2/demos/pull/529for an example of using the new function.rviz2improved the efficiency of 3-bytes pixel formatschanged the way inertias are computed to use ignition


key: chroma:document
string_value:
formatschanged the way inertias are computed to use ignition math rather than Ogre’s math libraries.geometry2Deprecation of TF2Error::NO_ERROR, etcThetf2library uses an enumeration calledTF2Errorto return errors. Unfortunately, one of the enumerators in there is calledNO_ERROR, which conflicts with a macro on Windows. To remedy this, a new set of enumerators inTF2Errorwere created, each with aTF2prefix. The previous enumerators are still available, but are now deprecated and will print a deprecation warning if used. All code that uses theTF2Errorenumerator should be updated to use the newTF2prefixed errors. Seehttps://github.com/ros2/geometry2/pull/349for more details.More intuitive command-line arguments for static_transform_publisherThestatic_transform_publisherprogram used to take arguments like:ros2runtf2_rosstatic_transform_publisher0000001foobar. The first three numbers are the translation x, y, and z, the next 4 are the quaternion x, y, z, and w, and the last two arguments are the parent and child


key: chroma:document
string_value:
z, and w, and the last two arguments are the parent and child frame IDs. While this worked, it had a couple of problems:The user had to specifyallof the arguments, even if only setting one numberReading the command-line to figure out what it was publishing was trickyTo fix both of these issues, the command-line handling has been changed to use flags instead, and all flags except for--frame-idand--child-frame-idare optional. Thus, the above command-line can be simplified to:ros2runtf2_rosstatic_transform_publisher--frame-idfoo--child-frame-idbarTo change just the translation x, the command-line would be:ros2runtf2_rosstatic_transform_publisher--x1.5--frame-idfoo--child-frame-idbar.The old-style arguments are still allowed in this release, but are deprecated and will print a warning. They will be removed in future releases. Seehttps://github.com/ros2/geometry2/pull/392for more details.Transform listener spin thread no longer executes node callbackstf2_ros::TransformListenerno longer spins on the provided node


key: chroma:document
string_value:
longer spins on the provided node object. Instead, it creates a callback group to execute callbacks on the entities it creates internally. This means if you have set the parameterspin_thread=truewhen creating a transform listener, you can no longer depend on your own callbacks to be executed. You must call aspinfunction on your node (e.g.rclcpp::spin), or add your node to your own executor.Related pull request:geometry2#442rosbag2New playback and recording controlsSeveral pull requests have been added to enhance the user’s control over playback of bags. Pull request931adds the ability to specify a time stamp to begin playing from. Due to pull request789it is now possible to delay the start of playback by a specified interval.Relatedly,rosbag2has gained new ways for users to control playback as it is happening. Pull request847adds keyboard controls for pausing, resuming, and playing the next message during playback from a terminal. It is also possible to start playback paused thanks to pull


key: chroma:document
string_value:
It is also possible to start playback paused thanks to pull requests905and904, which makes it easy for the user to initiate playback and then step through messages, such as when debugging a pipeline. Pull request836adds an interface for seeking within bags, allowing the user to move around within a bag during playback.Finally, a new snapshot mode has been added to recording in pull request851. This mode, useful for incident recording, allows recording to begin filling up buffers, but not begin writing data to disc until a service is called.Burst-mode playbackWhile the playback of data from a bag in real-time is the most well-known use case for bag files, there are situations where you want the data in the bag as fast as possible. With pull request977,rosbag2has gained the ability to “burst” data from the bag. In burst mode, the data is played back as fast as possible. This is useful in applications such as machine learning.Zero-Copy playbackBy default, if loaned message can be used, playback messages are


key: chroma:document
string_value:
default, if loaned message can be used, playback messages are published as loaned message. This can help to reduce the number of data copies, so there is a greater benefit for sending big data. Pull request981adds--disable-loan-messageoption for playback.Wait for an acknowledgmentThis new option will wait until all published messages are acknowledged by all subscribers or until the timeout elapses in millisecond before play is terminated. Especially for the case of sending message with big size in a short time. This option is valid only if the publisher’s QOS profile is RELIABLE. Pull request951adds--wait-for-all-ackedoption for playback.Bag editingrosbag2is taking steps towards enabling the editing of bags, such as removing all messages for one topic or merging multiple bags into a single bag. Pull request921adds bag rewriting and theros2bagconvertverb.Other changesPull request925makesrosbag2ignore “leaf topics” (topics without a publisher) when recording. These topics will no longer be automatically


key: chroma:document
string_value:
when recording. These topics will no longer be automatically added to the bag.Known IssuesWheninstalling ROS 2 on an Ubuntu 22.04 Jammy hostit is important to update your system before installing ROS 2 packages. It isparticularlyimportant to make sure thatsystemdandudevare updated to the latest available version otherwise installingros-humble-desktop, which depends onlibudev1, could cause the removal of system critical packages. Details can be found inros2/ros2#1272andLaunchpad #1974196When ROS 2 apt repositories are available, ROS 1 packages in Ubuntu are not installable.  See theros1_bridge on Ubuntu Jammydocument for more information.Some major Linux distributions have started patching Python to install packages to/usr/local, which is breaking some parts ofament_packageand builds withcolcon. In particular, using Ubuntu Jammy withsetuptoolsinstalled from pip will manifest this misbehavior, and is therefore not recommended. There is currently aproposed solutionwhich requires further testing before


key: chroma:document
string_value:
aproposed solutionwhich requires further testing before widespread release.ROS 2 bags that are split by size or duration are not played correctly. Only the last bag recorded is played. It is recommended to avoid splitting bags by size or duration. Details can be found inros2/rosbag2#966.Release TimelineMon. March 21, 2022 - Alpha + RMW freezePreliminary testing and stabilization of ROS Base[1]packages, and API and feature freeze for RMW provider packages.Mon. April 4, 2022 - FreezeAPI and feature freeze for ROS Base[1]packages in Rolling Ridley. Only bug fix releases should be made after this point. New packages can be released independently.Mon. April 18, 2022 - BranchBranch from Rolling Ridley.rosdistrois reopened for Rolling PRs for ROS Base[1]packages. Humble development shifts fromros-rolling-*packages toros-humble-*packages.Mon. April 25, 2022 - BetaUpdated releases of ROS Desktop[2]packages available. Call for general testing.Mon. May 16, 2022 - Release CandidateRelease Candidate packages are built.


key: chroma:document
string_value:
2022 - Release CandidateRelease Candidate packages are built. Updated releases of ROS Desktop[2]packages available.Thu. May 19, 2022 - Distro FreezeFreeze rosdistro. No PRs for Humble on therosdistrorepo will be merged (reopens after the release announcement).Mon. May 23, 2022 - General AvailabilityRelease announcement.rosdistrois reopened for Humble PRs.[1](1,2,3)Theros_basevariant is described inREP 2001 (ros-base).[2](1,2)Thedesktopvariant is described inREP 2001 (desktop-variants).


key: chroma:document
string_value:
Code Examples:

Language: unknown

project(my_project)add_library(my_lib...)ament_generate_version_header(my_lib)

Language: unknown

#include<my_project/version.h>

Language: unknown

set(VERSION_HEADER${CMAKE_INSTALL_PREFIX}/include/my_project/my_project/version.h)

Language: unknown

<launch><set_envname="FOO"value="1"/><group><set_envname="FOO"value="2"/></group><executablecmd="echo $FOO"output="screen"shell="true"/></launch>

Language: unknown

importlaunchimportlaunch.actionsdefgenerate_launch_description():returnlaunch.LaunchDescription([launch.actions.SetEnvironmentVariable(name='FOO',value='1'),launch.actions.GroupAction([launch.actions.SetEnvironmentVariable(name='FOO',value='2'),]),launch.actions.ExecuteProcess(cmd=['echo','$FOO'],output='screen',shell=True),])

Language: unknown

<launch><logmessage="$(eval 'ceil(pi)')"/></launch>


key: chroma:document
string_value:
<launch><logmessage="$(eval 'ceil(pi)')"/></launch>

Language: unknown <launch><letname="p"value="true"/><letname="q"value="false"/><groupif="$(or $(var p) $(var q))"><logmessage="The first condition is true"/></group><groupunless="$(and $(var p) $(var q))"><logmessage="The second condition is false"/></group><groupif="$(not $(var q))"><logmessage="The third condition is true"/></group></launch>

Language: unknown

<launch><nodepkg="demo_nodes_cpp"exec="talker"ros_args="-

log

level debug"/></launch>

Language: unknown

launch:

node:pkg:demo_nodes_cppexec:talkerros_args:'-

log

leveldebug'

Language: unknown

fromlaunchimportLaunchDescriptionimportlaunch_ros.actionsdefgenerate_launch_description():returnLaunchDescription([launch_ros.actions.Node(package='demo_nodes_cpp',executable='talker',ros_arguments=['-

log

level','debug'],),])

Language: unknown


key: chroma:document
string_value:
log

level','debug'],),])

Language: unknown

<launch><node_containerpkg="rclcpp_components"exec="component_container"name="my_container"namespace=""><composable_nodepkg="composition"plugin="composition::Talker"name="talker"/></node_container><load_composable_nodetarget="my_container"><composable_nodepkg="composition"plugin="composition::Listener"name="listener"/></load_composable_node></launch>

Language: unknown

launch:

node_container:pkg:rclcpp_componentsexec:component_containername:my_containernamespace:''composable_node:

pkg:compositionplugin:composition::Talkername:talker

load_composable_node:target:my_containercomposable_node:

pkg:compositionplugin:composition::Listenername:listener

Language: unknown <launch><set_parametername="foo"value="bar"/><logmessage="Parameter foo has value $(param foo)"/></launch>

Language: unknown

transforms:


key: chroma:document
string_value:
Language: unknown

transforms:

header:stamp:sec:1651172841nanosec:433705575frame_id:single_rrbot_link3child_frame_id:single_rrbot_camera_linktransform:translation:x:0.05y:0.0z:0.9rotation:x:0.0y:0.0z:0.0w:1.0

Language: unknown

transforms:[{header:{stamp:{sec:1651172841,nanosec:433705575},frame_id:single_rrbot_link3},child_frame_id:single_rrbot_camera_link,transform:{translation:{x:0.05,y:0.0,z:0.9},rotation:{x:0.0,y:0.0,z:0.0,w:1.0}}}]

Language: unknown

ros2topicecho-

filter'm.data.startswith("foo")` /chatter

Language: unknown

/opt/ros/galactic/include/

├── rcl

│   ├── node.h

├── rclcpp

│   ├── node.hpp

Language: unknown /opt/ros/humble/include ├── rcl │   └── rcl │       ├── node.h ├── rclcpp │   └── rclcpp │       ├── node.hpp


key: chroma:document
string_value:
Language: unknown # Texture resource is a special URI that can either reference a texture file in# a format acceptable to (resource retriever)[https://index.ros.org/p/resource_retriever/]# or an embedded texture via a string matching the format:#   "embedded://texture_name"stringtexture_resource# An image to be loaded into the rendering engine as the texture for this marker.# This will be used iff texture_resource is set to embedded.sensor_msgs/CompressedImagetexture# Location of each vertex within the texture; in the range: [0.0-1.0]UVCoordinate[]uv_coordinates

Language: unknown # The filename is used for both debug purposes and to provide a file extension# for whatever parser is used.stringfilename# This stores the raw text of the mesh file.uint8[]data

Language: unknown


key: chroma:document
string_value:
Language: unknown

template<>structrclcpp::TypeAdapter<std::string,std_msgs::msg::String>{usingis_specialized=std::true_type;usingcustom_type=std::string;usingros_message_type=std_msgs::msg::String;staticvoidconvert_to_ros_message(constcustom_type&source,ros_message_type&destination){destination.data=source;}staticvoidconvert_to_custom(constros_message_type&source,custom_type&destination){destination=source.data;}};

Language: unknown usingMyAdaptedType=TypeAdapter<std::string,std_msgs::msg::String>;// Publish a std::stringautopub=node->create_publisher<MyAdaptedType>(...);std::stringcustom_msg="My std::string"pub->publish(custom_msg);// Pass a std::string to a subscription's callbackautosub=node->create_subscription<MyAdaptedType>("topic",10,[](conststd::string&msg){...});

Language: unknown autofuture=client->async_send_request(req);...do_something_with_response(future.get());...do_something_else_with_response(future.get());// this will throw an exception now!!

Language: unknown

autofuture=client


key: chroma:document
string_value:
Language: unknown

autofuture=client

>async_send_request(req);...autoresponse=future.get();do_something_with_response(response);...do_something_else_with_response(response);

Language: unknown

autopub=node

>create_publisher<std_msgs::msg::String>(...);...pub

>publish(my_msg);...pub

>wait_for_all_acked();// or pub

>wait_for_all_acked(timeout)

Language: unknown

ros2echo/chatter|grep"Hello"

Language: unknown ros2 topic pub -1 -w 3 /chatter std_msgs/msg/String "{data: 'foo'}"

Language: unknown

ros2paramdump/my_node_name

Language: unknown

ros2paramdump/my_node_name>my_node_name.yaml


key: chroma:document
string_value:
Title: Writing an action server and client (Python) URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Writing-an-Action-Server-Client/Py.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Writing an action server and client (Python)Goal:Implement an action server and client in Python.Tutorial level:IntermediateTime:15 minutesContentsBackgroundPrerequisitesTasks1 Writing an action server2 Writing an action clientSummaryRelated contentBackgroundActions are a form of asynchronous communication in ROS 2.Action clientssend goal requests toaction servers.Action serverssend goal feedback and results toaction clients.PrerequisitesYou will need thecustom_action_interfacespackage and theFibonacci.actioninterface defined in the previous tutorial,Creating an action.Tasks1 Writing an action serverLet’s focus on writing an action server that computes the Fibonacci sequence using the action we created in theCreating an actiontutorial.Until now, you’ve created packages and usedros2runto run your nodes. To keep things simple in this tutorial, however, we’ll scope the action server to a single file. If you’d like to see what a complete package for the actions tutorials looks like, check


key: chroma:document
string_value:
a complete package for the actions tutorials looks like, check outaction_tutorials.Open a new file in your home directory, let’s call itfibonacci_action_server.py, and add the following code:importrclpyfromrclpy.actionimportActionServerfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionServer(Node):def__init__(self):super().__init__('fibonacci_action_server')self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')result=Fibonacci.Result()returnresultdefmain(args=None):rclpy.init(args=args)fibonacci_action_server=FibonacciActionServer()rclpy.spin(fibonacci_action_server)if__name__=='__main__':main()Line 8 defines a classFibonacciActionServerthat is a subclass ofNode. The class is initialized by calling theNodeconstructor, naming our nodefibonacci_action_server:super().__init__('fibonacci_action_server')In the constructor we also instantiate a new action


key: chroma:document
string_value:
the constructor we also instantiate a new action server:self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)An action server requires four arguments:A ROS 2 node to add the action client to:self.The type of the action:Fibonacci(imported in line 5).The action name:'fibonacci'.A callback function for executing accepted goals:self.execute_callback. This callbackmustreturn a result message for the action type.We also define anexecute_callbackmethod in our class:defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')result=Fibonacci.Result()returnresultThis is the method that will be called to execute a goal once it is accepted.Let’s try running our action server:LinuxmacOSWindowspython3fibonacci_action_server.pypython3fibonacci_action_server.pypythonfibonacci_action_server.pyIn another terminal, we can use the command line interface to send a goal:ros2actionsend_goalfibonaccicustom_action_interfaces/action/Fibonacci"{order: 5}"In the terminal that is


key: chroma:document
string_value:
5}"In the terminal that is running the action server, you should see a logged message “Executing goal…” followed by a warning that the goal state was not set. By default, if the goal handle state is not set in the execute callback it assumes theabortedstate.We can callsucceed()on the goal handle to indicate that the goal was successful:defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')goal_handle.succeed()result=Fibonacci.Result()returnresultNow if you restart the action server and send another goal, you should see the goal finished with the statusSUCCEEDED.Now let’s make our goal execution actually compute and return the requested Fibonacci sequence:defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')sequence=[0,1]foriinrange(1,goal_handle.request.order):sequence.append(sequence[i]+sequence[i-1])goal_handle.succeed()result=Fibonacci.Result()result.sequence=sequencereturnresultAfter computing the sequence, we assign it to the result message field


key: chroma:document
string_value:
the sequence, we assign it to the result message field before returning.Again, restart the action server and send another goal. You should see the goal finish with the proper result sequence.1.2 Publishing feedbackOne of the nice things about actions is the ability to provide feedback to an action client during goal execution. We can make our action server publish feedback for action clients by calling the goal handle’spublish_feedback()method.We’ll replace thesequencevariable, and use a feedback message to store the sequence instead. After every update of the feedback message in the for-loop, we publish the feedback message and sleep for dramatic


key: chroma:document
string_value:
we publish the feedback message and sleep for dramatic effect:importtimeimportrclpyfromrclpy.actionimportActionServerfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionServer(Node):def__init__(self):super().__init__('fibonacci_action_server')self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)defexecute_callback(self,goal_handle):self.get_logger().info('Executing


key: chroma:document
string_value:
goal...')feedback_msg=Fibonacci.Feedback()feedback_msg.partial_sequence=[0,1]foriinrange(1,goal_handle.request.order):feedback_msg.partial_sequence.append(feedback_msg.partial_sequence[i]+feedback_msg.partial_sequence[i-1])self.get_logger().info('Feedback:{0}'.format(feedback_msg.partial_sequence))goal_handle.publish_feedback(feedback_msg)time.sleep(1)goal_handle.succeed()result=Fibonacci.Result()result.sequence=feedback_msg.partial_sequencereturnresultdefmain(args=None):rclpy.init(args=args)fibonacci_action_server=FibonacciActionServer()rclpy.spin(fibonacci_action_server)if__name__=='__main__':main()After restarting the action server, we can confirm that feedback is now published by using the command line tool with the--feedbackoption:ros2actionsend_goal--feedbackfibonaccicustom_action_interfaces/action/Fibonacci"{order: 5}"2 Writing an action clientWe’ll also scope the action client to a single file. Open a new file, let’s call itfibonacci_action_client.py, and add the following boilerplate


key: chroma:document
string_value:
itfibonacci_action_client.py, and add the following boilerplate code:importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()returnself._action_client.send_goal_async(goal_msg)defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()future=action_client.send_goal(10)rclpy.spin_until_future_complete(action_client,future)if__name__=='__main__':main()We’ve defined a classFibonacciActionClientthat is a subclass ofNode. The class is initialized by calling theNodeconstructor, naming our nodefibonacci_action_client:super().__init__('fibonacci_action_client')Also in the class constructor, we create an action client using the custom action definition from the previous tutorial


key: chroma:document
string_value:
using the custom action definition from the previous tutorial onCreating an action:self._action_client=ActionClient(self,Fibonacci,'fibonacci')We create anActionClientby passing it three arguments:A ROS 2 node to add the action client to:selfThe type of the action:FibonacciThe action name:'fibonacci'Our action client will be able to communicate with action servers of the same action name and type.We also define a methodsend_goalin theFibonacciActionClientclass:defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()returnself._action_client.send_goal_async(goal_msg)This method waits for the action server to be available, then sends a goal to the server. It returns a future that we can later wait on.After the class definition, we define a functionmain()that initializes ROS 2 and creates an instance of ourFibonacciActionClientnode. It then sends a goal and waits until that goal has been completed.Finally, we callmain()in the entry point of our Python


key: chroma:document
string_value:
we callmain()in the entry point of our Python program.Let’s test our action client by first running the action server built earlier:LinuxmacOSWindowspython3fibonacci_action_server.pypython3fibonacci_action_server.pypythonfibonacci_action_server.pyIn another terminal, run the action client:LinuxmacOSWindowspython3fibonacci_action_client.pypython3fibonacci_action_client.pypythonfibonacci_action_client.pyYou should see messages printed by the action server as it successfully executes the goal:[INFO][fibonacci_action_server]:Executinggoal...[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2,3])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2,3,5])# etc.The action client should start up, and then quickly finish. At this point, we have a functioning action client, but we don’t see any results or get any feedback.2.1 Getting a resultSo we can send a goal, but how do we know


key: chroma:document
string_value:
Getting a resultSo we can send a goal, but how do we know when it is completed? We can get the result information with a couple steps. First, we need to get a goal handle for the goal we sent. Then, we can use the goal handle to request the result.Here’s the complete code for this example:importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()self._send_goal_future=self._action_client.send_goal_async(goal_msg)self._send_goal_future.add_done_callback(self.goal_response_callback)defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted


key: chroma:document
string_value:
rejected :(')returnself.get_logger().info('Goal accepted :)')self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()action_client.send_goal(10)rclpy.spin(action_client)if__name__=='__main__':main()TheActionClient.send_goal_async()method returns a future to a goal handle. First we register a callback for when the future is complete:self._send_goal_future.add_done_callback(self.goal_response_callback)Note that the future is completed when an action server accepts or rejects the goal request. Let’s look at thegoal_response_callbackin more detail. We can check to see if the goal was rejected and return early since we know there will be no


key: chroma:document
string_value:
was rejected and return early since we know there will be no result:defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted :)')Now that we’ve got a goal handle, we can use it to request the result with the methodget_result_async(). Similar to sending the goal, we will get a future that will complete when the result is ready. Let’s register a callback just like we did for the goal response:self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)In the callback, we log the result sequence and shutdown ROS 2 for a clean exit:defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()With an action server running in a separate terminal, go ahead and try running our Fibonacci action


key: chroma:document
string_value:
terminal, go ahead and try running our Fibonacci action client!LinuxmacOSWindowspython3fibonacci_action_client.pypython3fibonacci_action_client.pypythonfibonacci_action_client.pyYou should see logged messages for the goal being accepted and the final result.2.2 Getting feedbackOur action client can send goals. Nice! But it would be great if we could get some feedback about the goals we send from the action server.Here’s the complete code for this


key: chroma:document
string_value:
send from the action server.Here’s the complete code for this example:importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()self._send_goal_future=self._action_client.send_goal_async(goal_msg,feedback_callback=self.feedback_callback)self._send_goal_future.add_done_callback(self.goal_response_callback)defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted


key: chroma:document
string_value:
rejected :(')returnself.get_logger().info('Goal accepted :)')self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()deffeedback_callback(self,feedback_msg):feedback=feedback_msg.feedbackself.get_logger().info('Received feedback:{0}'.format(feedback.partial_sequence))defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()action_client.send_goal(10)rclpy.spin(action_client)if__name__=='__main__':main()Here’s the callback function for feedback messages:deffeedback_callback(self,feedback_msg):feedback=feedback_msg.feedbackself.get_logger().info('Received feedback:{0}'.format(feedback.partial_sequence))In the callback we get the feedback portion of the message and print thepartial_sequencefield to the screen.We need to register the callback with the action client. This is achieved by


key: chroma:document
string_value:
the callback with the action client. This is achieved by additionally passing the callback to the action client when we send a goal:self._send_goal_future=self._action_client.send_goal_async(goal_msg,feedback_callback=self.feedback_callback)We’re all set. If we run our action client, you should see feedback being printed to the screen.SummaryIn this tutorial, you put together a Python action server and action client line by line, and configured them to exchange goals, feedback, and results.Related contentThere are several ways you could write an action server and client in Python; check out theminimal_action_serverandminimal_action_clientpackages in theros2/examplesrepo.For more detailed information about ROS actions, please refer to thedesign article.


key: chroma:document
string_value:
Code Examples:

Language: unknown

importrclpyfromrclpy.actionimportActionServerfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionServer(Node):def__init__(self):super().__init__('fibonacci_action_server')self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')result=Fibonacci.Result()returnresultdefmain(args=None):rclpy.init(args=args)fibonacci_action_server=FibonacciActionServer()rclpy.spin(fibonacci_action_server)if__name__=='__main__':main()

Language: unknown

super().__init__('fibonacci_action_server')

Language: unknown

self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)

Language: unknown

defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')result=Fibonacci.Result()returnresult

Language: unknown

python3fibonacci_action_server.py

Language: unknown

python3fibonacci_action_server.py


key: chroma:document
string_value:
Language: unknown

python3fibonacci_action_server.py

Language: unknown

pythonfibonacci_action_server.py

Language: unknown

ros2actionsend_goalfibonaccicustom_action_interfaces/action/Fibonacci"{order: 5}"

Language: unknown

defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')goal_handle.succeed()result=Fibonacci.Result()returnresult

Language: unknown

defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')sequence=[0,1]foriinrange(1,goal_handle.request.order):sequence.append(sequence[i]+sequence[i

1])goal_handle.succeed()result=Fibonacci.Result()result.sequence=sequencereturnresult

Language: unknown


key: chroma:document
string_value:
Language: unknown

importtimeimportrclpyfromrclpy.actionimportActionServerfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionServer(Node):def__init__(self):super().__init__('fibonacci_action_server')self._action_server=ActionServer(self,Fibonacci,'fibonacci',self.execute_callback)defexecute_callback(self,goal_handle):self.get_logger().info('Executing goal...')feedback_msg=Fibonacci.Feedback()feedback_msg.partial_sequence=[0,1]foriinrange(1,goal_handle.request.order):feedback_msg.partial_sequence.append(feedback_msg.partial_sequence[i]+feedback_msg.partial_sequence[i

1])self.get_logger().info('Feedback:{0}'.format(feedback_msg.partial_sequence))goal_handle.publish_feedback(feedback_msg)time.sleep(1)goal_handle.succeed()result=Fibonacci.Result()result.sequence=feedback_msg.partial_sequencereturnresultdefmain(args=None):rclpy.init(args=args)fibonacci_action_server=FibonacciActionServer()rclpy.spin(fibonacci_action_server)if__name__=='__main__':main()


key: chroma:document
string_value:
Language: unknown

ros2actionsend_goal-

feedbackfibonaccicustom_action_interfaces/action/Fibonacci"{order: 5}"

Language: unknown

importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()returnself._action_client.send_goal_async(goal_msg)defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()future=action_client.send_goal(10)rclpy.spin_until_future_complete(action_client,future)if__name__=='__main__':main()

Language: unknown

super().__init__('fibonacci_action_client')

Language: unknown

self._action_client=ActionClient(self,Fibonacci,'fibonacci')

Language: unknown


key: chroma:document
string_value:
Language: unknown

defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()returnself._action_client.send_goal_async(goal_msg)

Language: unknown

python3fibonacci_action_server.py

Language: unknown

python3fibonacci_action_server.py

Language: unknown

pythonfibonacci_action_server.py

Language: unknown

python3fibonacci_action_client.py

Language: unknown

python3fibonacci_action_client.py

Language: unknown

pythonfibonacci_action_client.py

Language: unknown

[INFO][fibonacci_action_server]:Executinggoal...[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2,3])[INFO][fibonacci_action_server]:Feedback:array('i',[0,1,1,2,3,5])# etc.


key: chroma:document
string_value:
Language: unknown importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()self._send_goal_future=self._action_client.send_goal_async(goal_msg)self._send_goal_future.add_done_callback(self.goal_response_callback)defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted


key: chroma:document
string_value:
rejected :(')returnself.get_logger().info('Goal accepted :)')self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()action_client.send_goal(10)rclpy.spin(action_client)if__name__=='__main__':main()


key: chroma:document
string_value:
Language: unknown

self._send_goal_future.add_done_callback(self.goal_response_callback)

Language: unknown defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted :)')

Language: unknown

self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)

Language: unknown

defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()

Language: unknown

python3fibonacci_action_client.py

Language: unknown

python3fibonacci_action_client.py

Language: unknown

pythonfibonacci_action_client.py


key: chroma:document
string_value:
Language: unknown importrclpyfromrclpy.actionimportActionClientfromrclpy.nodeimportNodefromcustom_action_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__('fibonacci_action_client')self._action_client=ActionClient(self,Fibonacci,'fibonacci')defsend_goal(self,order):goal_msg=Fibonacci.Goal()goal_msg.order=orderself._action_client.wait_for_server()self._send_goal_future=self._action_client.send_goal_async(goal_msg,feedback_callback=self.feedback_callback)self._send_goal_future.add_done_callback(self.goal_response_callback)defgoal_response_callback(self,future):goal_handle=future.result()ifnotgoal_handle.accepted:self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted


key: chroma:document
string_value:
rejected :(')returnself.get_logger().info('Goal accepted :)')self._get_result_future=goal_handle.get_result_async()self._get_result_future.add_done_callback(self.get_result_callback)defget_result_callback(self,future):result=future.result().resultself.get_logger().info('Result:{0}'.format(result.sequence))rclpy.shutdown()deffeedback_callback(self,feedback_msg):feedback=feedback_msg.feedbackself.get_logger().info('Received feedback:{0}'.format(feedback.partial_sequence))defmain(args=None):rclpy.init(args=args)action_client=FibonacciActionClient()action_client.send_goal(10)rclpy.spin(action_client)if__name__=='__main__':main()


key: chroma:document
string_value:
Language: unknown

deffeedback_callback(self,feedback_msg):feedback=feedback_msg.feedbackself.get_logger().info('Received feedback:{0}'.format(feedback.partial_sequence))

Language: unknown

self._send_goal_future=self._action_client.send_goal_async(goal_msg,feedback_callback=self.feedback_callback)


key: chroma:document
string_value:
Title: eProsima Fast DDS

URL: https://docs.ros.org/en/jazzy/Installation/DDS

Implementations/Working

with

eProsima

Fast

DDS.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
eProsima Fast DDSeProsima Fast DDS is a complete open-source DDS implementation for real time embedded architectures and operating systems. See also:https://www.eprosima.com/index.php/products-all/eprosima-fast-ddsPrerequisitesHaverosdep installed.Install packagesThe easiest way is to install from ROS 2 apt repository.sudoaptinstallros-jazzy-rmw-fastrtps-cppBuild from source codeBuilding from source code is also another way to install.First, clone Fast DDS and rmw_fastrtps in the ROS 2 workspace source directory.cdros2_ws/src gitclonehttps://github.com/ros2/rmw_fastrtpsros2/rmw_fastrtps-bjazzy gitclonehttps://github.com/eProsima/Fast-DDSeProsima/fastrtpsThen, install necessary packages for Fast DDS.cd.. rosdepinstall--fromsrc-iFinally, run colcon build.colconbuild--symlink-installSwitch to rmw_fastrtpsThe eProsima Fast DDS RMW can be selected by specifying the environment variable:exportRMW_IMPLEMENTATION=rmw_fastrtps_cppSee also:Working with multiple RMW implementationsRun the talker and listenerNow


key: chroma:document
string_value:
multiple RMW implementationsRun the talker and listenerNow runtalkerandlistenerto test Fast DDS.ros2rundemo_nodes_cpptalkerros2rundemo_nodes_cpplistener


key: chroma:document
string_value:
Code Examples:

Language: unknown

sudoaptinstallros

jazzy

rmw

fastrtps

cpp

Language: unknown

cdros2_ws/src

gitclonehttps://github.com/ros2/rmw_fastrtpsros2/rmw_fastrtps

bjazzy

gitclonehttps://github.com/eProsima/Fast

DDSeProsima/fastrtps

Language: unknown

cd..

rosdepinstall-

fromsrc

i

Language: unknown

colconbuild-

symlink

install

Language: unknown

exportRMW_IMPLEMENTATION=rmw_fastrtps_cpp

Language: unknown

ros2rundemo_nodes_cpptalker

Language: unknown

ros2rundemo_nodes_cpplistener


key: chroma:document
string_value:
Title: Adding a frame (Python) URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Tf2/Adding-A-Frame-Py.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Adding a frame (Python)Goal:Learn how to to add an extra frame to tf2.Tutorial level:IntermediateTime:15 minutesContentsBackgroundtf2 treeTasks1 Write the fixed frame broadcaster1.1 Examine the code1.2 Add an entry point1.3 Write the launch file1.4 Build1.5 Run2 Write the dynamic frame broadcaster2.1 Examine the code2.2 Add an entry point2.3 Write the launch file2.4 Build1.5 RunSummaryBackgroundIn previous tutorials, we recreated the turtle demo by writing atf2 broadcasterand atf2 listener. This tutorial will teach you how to add extra fixed and dynamic frames to the transformation tree. In fact, adding a frame in tf2 is very similar to creating the tf2 broadcaster, but this example will show you some additional features of tf2.For many tasks related to transformations, it is easier to think inside a local frame. For example, it is easiest to reason about laser scan measurements in a frame at the center of the laser scanner. tf2 allows you to define a local frame for each sensor, link, or joint in your


key: chroma:document
string_value:
to define a local frame for each sensor, link, or joint in your system. When transforming from one frame to another, tf2 will take care of all the hidden intermediate frame transformations that are introduced.tf2 treetf2 builds up a tree structure of frames and, thus, does not allow a closed loop in the frame structure. This means that a frame only has one single parent, but it can have multiple children. Currently, our tf2 tree contains three frames:world,turtle1andturtle2. The two turtle frames are children of theworldframe. If we want to add a new frame to tf2, one of the three existing frames needs to be the parent frame, and the new one will become its child frame.Tasks1 Write the fixed frame broadcasterIn our turtle example, we’ll add a new framecarrot1, which will be the child of theturtle1. This frame will serve as the goal for the second turtle.Let’s first create the source files. Go to thelearning_tf2_pypackage we created in the previous tutorials. Inside


key: chroma:document
string_value:
we created in the previous tutorials. Inside thesrc/learning_tf2_py/learning_tf2_pydirectory download the fixed frame broadcaster code by entering the following command:LinuxmacOSWindowswget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.pywget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.pyIn a Windows command line prompt:curl -sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py -o fixed_frame_tf2_broadcaster.pyOr in powershell:curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py -o fixed_frame_tf2_broadcaster.pyNow open the file


key: chroma:document
string_value:
-o fixed_frame_tf2_broadcaster.pyNow open the file calledfixed_frame_tf2_broadcaster.py.fromgeometry_msgs.msgimportTransformStampedimportrclpyfromrclpy.nodeimportNodefromtf2_rosimportTransformBroadcasterclassFixedFrameBroadcaster(Node):def__init__(self):super().__init__('fixed_frame_tf2_broadcaster')self.tf_broadcaster=TransformBroadcaster(self)self.timer=self.create_timer(0.1,self.broadcast_timer_callback)defbroadcast_timer_callback(self):t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=0.0t.transform.translation.y=2.0t.transform.translation.z=0.0t.transform.rotation.x=0.0t.transform.rotation.y=0.0t.transform.rotation.z=0.0t.transform.rotation.w=1.0self.tf_broadcaster.sendTransform(t)defmain():rclpy.init()node=FixedFrameBroadcaster()try:rclpy.spin(node)exceptKeyboardInterrupt:passrclpy.shutdown()The code is very similar to the tf2 broadcaster tutorial example and the only difference is that the transform here


key: chroma:document
string_value:
example and the only difference is that the transform here does not change over time.1.1 Examine the codeLet’s take a look at the key lines in this piece of code. Here we create a new transform, from the parentturtle1to the new childcarrot1. Thecarrot1frame is 2 meters offset in y axis in terms of theturtle1frame.t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=0.0t.transform.translation.y=2.0t.transform.translation.z=0.01.2 Add an entry pointTo allow theros2runcommand to run your node, you must add the entry point tosetup.py(located in thesrc/learning_tf2_pydirectory).Add the following line between the'console_scripts':brackets:'fixed_frame_tf2_broadcaster = learning_tf2_py.fixed_frame_tf2_broadcaster:main',1.3 Write the launch fileNow let’s create a launch file for this example. With your text editor, create a new file calledturtle_tf2_fixed_frame_demo_launch.pyin thesrc/learning_tf2_py/launchdirectory, and


key: chroma:document
string_value:
thesrc/learning_tf2_py/launchdirectory, and add the following lines:importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcefromlaunch_ros.actionsimportNodedefgenerate_launch_description():demo_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_tf2_py'),'launch'),'/turtle_tf2_demo_launch.py']),)returnLaunchDescription([demo_nodes,Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',),])This launch file imports the required packages and then creates ademo_nodesvariable that will store nodes that we created in the previous tutorial’s launch file.The last part of the code will add our fixedcarrot1frame to the turtlesim world using


key: chroma:document
string_value:
will add our fixedcarrot1frame to the turtlesim world using ourfixed_frame_tf2_broadcasternode.Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',),1.4 BuildRunrosdepin the root of your workspace to check for missing dependencies.LinuxmacOSWindowsrosdep install -i --from-path src --rosdistro jazzy -yrosdep only runs on Linux, so you will need to installgeometry_msgsandturtlesimdependencies yourselfrosdep only runs on Linux, so you will need to installgeometry_msgsandturtlesimdependencies yourselfStill in the root of your workspace, build your package:LinuxmacOSWindowscolcon build --packages-select learning_tf2_pycolcon build --packages-select learning_tf2_pycolcon build --merge-install --packages-select learning_tf2_pyOpen a new terminal, navigate to the root of your workspace, and source the setup files:LinuxmacOSWindows. install/setup.bash. install/setup.bash#CMDcall install\setup.bat#Powershell.\install\setup.ps11.5 RunNow you can start the turtle


key: chroma:document
string_value:
RunNow you can start the turtle broadcaster demo:ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo_launch.pyYou should notice that the newcarrot1frame appeared in the transformation tree.If you drive the first turtle around, you should notice that the behavior didn’t change from the previous tutorial, even though we added a new frame. That’s because adding an extra frame does not affect the other frames and our listener is still using the previously defined frames.Therefore if we want our second turtle to follow the carrot instead of the first turtle, we need to change value of thetarget_frame. This can be done two ways. One way is to pass thetarget_frameargument to the launch file directly from the console:ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo_launch.py target_frame:=carrot1The second way is to update the launch file. To do so, open theturtle_tf2_fixed_frame_demo_launch.pyfile, and add the'target_frame':'carrot1'parameter


key: chroma:document
string_value:
and add the'target_frame':'carrot1'parameter vialaunch_argumentsargument.defgenerate_launch_description():demo_nodes=IncludeLaunchDescription(...,launch_arguments={'target_frame':'carrot1'}.items(),)Now rebuild the package, restart theturtle_tf2_fixed_frame_demo_launch.py, and you’ll see the second turtle following the carrot instead of the first turtle!2 Write the dynamic frame broadcasterThe extra frame we published in this tutorial is a fixed frame that doesn’t change over time in relation to the parent frame. However, if you want to publish a moving frame you can code the broadcaster to change the frame over time. Let’s change ourcarrot1frame so that it changes relative toturtle1frame over time. Go to thelearning_tf2_pypackage we created in the previous tutorial. Inside thesrc/learning_tf2_py/learning_tf2_pydirectory download the dynamic frame broadcaster code by entering the following command:LinuxmacOSWindowswget


key: chroma:document
string_value:
code by entering the following command:LinuxmacOSWindowswget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.pywget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.pyIn a Windows command line prompt:curl -sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py -o dynamic_frame_tf2_broadcaster.pyOr in powershell:curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py -o dynamic_frame_tf2_broadcaster.pyNow open the file


key: chroma:document
string_value:
-o dynamic_frame_tf2_broadcaster.pyNow open the file calleddynamic_frame_tf2_broadcaster.py:importmathfromgeometry_msgs.msgimportTransformStampedimportrclpyfromrclpy.nodeimportNodefromtf2_rosimportTransformBroadcasterclassDynamicFrameBroadcaster(Node):def__init__(self):super().__init__('dynamic_frame_tf2_broadcaster')self.tf_broadcaster=TransformBroadcaster(self)self.timer=self.create_timer(0.1,self.broadcast_timer_callback)defbroadcast_timer_callback(self):seconds,_=self.get_clock().now().seconds_nanoseconds()x=seconds*math.pit=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=10*math.sin(x)t.transform.translation.y=10*math.cos(x)t.transform.translation.z=0.0t.transform.rotation.x=0.0t.transform.rotation.y=0.0t.transform.rotation.z=0.0t.transform.rotation.w=1.0self.tf_broadcaster.sendTransform(t)defmain():rclpy.init()node=DynamicFrameBroadcaster()try:rclpy.spin(node)exceptKeyboardInterrupt:passrclpy.shutdown()2.1


key: chroma:document
string_value:
Examine the codeInstead of a fixed definition of our x and y offsets, we are using thesin()andcos()functions on the current time so that the offset ofcarrot1is constantly changing.seconds,_=self.get_clock().now().seconds_nanoseconds()x=seconds*math.pi...t.transform.translation.x=10*math.sin(x)t.transform.translation.y=10*math.cos(x)2.2 Add an entry pointTo allow theros2runcommand to run your node, you must add the entry point tosetup.py(located in thesrc/learning_tf2_pydirectory).Add the following line between the'console_scripts':brackets:'dynamic_frame_tf2_broadcaster = learning_tf2_py.dynamic_frame_tf2_broadcaster:main',2.3 Write the launch fileTo test this code, create a new launch fileturtle_tf2_dynamic_frame_demo_launch.pyin thesrc/learning_tf2_py/launchdirectory and paste the following


key: chroma:document
string_value:
thesrc/learning_tf2_py/launchdirectory and paste the following code:importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcefromlaunch_ros.actionsimportNodedefgenerate_launch_description():demo_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_tf2_py'),'launch'),'/turtle_tf2_demo_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)returnLaunchDescription([demo_nodes,Node(package='learning_tf2_py',executable='dynamic_frame_tf2_broadcaster',name='dynamic_broadcaster',),])2.4 BuildRunrosdepin the root of your workspace to check for missing dependencies.LinuxmacOSWindowsrosdep install -i --from-path src --rosdistro jazzy -yrosdep only runs on Linux, so you will need to installgeometry_msgsandturtlesimdependencies yourselfrosdep only runs on Linux, so you will need to


key: chroma:document
string_value:
yourselfrosdep only runs on Linux, so you will need to installgeometry_msgsandturtlesimdependencies yourselfStill in the root of your workspace, build your package:LinuxmacOSWindowscolcon build --packages-select learning_tf2_pycolcon build --packages-select learning_tf2_pycolcon build --merge-install --packages-select learning_tf2_pyOpen a new terminal, navigate to the root of your workspace, and source the setup files:LinuxmacOSWindows. install/setup.bash. install/setup.bash#CMDcall install\setup.bat#Powershell.\install\setup.ps11.5 RunNow you can start the dynamic frame demo:ros2 launch learning_tf2_py turtle_tf2_dynamic_frame_demo_launch.pyYou should see that the second turtle is following the carrot’s position that is constantly changing.SummaryIn this tutorial, you learned about the tf2 transformation tree, its structure, and its features. You also learned that it is easiest to think inside a local frame, and learned to add extra fixed and dynamic frames for that local frame.


key: chroma:document
string_value:
Code Examples:

Language: unknown

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py

Language: unknown

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py

Language: unknown

curl

sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py

o fixed_frame_tf2_broadcaster.py

Language: unknown

curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py

o fixed_frame_tf2_broadcaster.py

Language: unknown


key: chroma:document
string_value:
o fixed_frame_tf2_broadcaster.py

Language: unknown

fromgeometry_msgs.msgimportTransformStampedimportrclpyfromrclpy.nodeimportNodefromtf2_rosimportTransformBroadcasterclassFixedFrameBroadcaster(Node):def__init__(self):super().__init__('fixed_frame_tf2_broadcaster')self.tf_broadcaster=TransformBroadcaster(self)self.timer=self.create_timer(0.1,self.broadcast_timer_callback)defbroadcast_timer_callback(self):t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=0.0t.transform.translation.y=2.0t.transform.translation.z=0.0t.transform.rotation.x=0.0t.transform.rotation.y=0.0t.transform.rotation.z=0.0t.transform.rotation.w=1.0self.tf_broadcaster.sendTransform(t)defmain():rclpy.init()node=FixedFrameBroadcaster()try:rclpy.spin(node)exceptKeyboardInterrupt:passrclpy.shutdown()

Language: unknown


key: chroma:document
string_value:
Language: unknown

t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=0.0t.transform.translation.y=2.0t.transform.translation.z=0.0

Language: unknown

'fixed_frame_tf2_broadcaster = learning_tf2_py.fixed_frame_tf2_broadcaster:main',

Language: unknown

importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcefromlaunch_ros.actionsimportNodedefgenerate_launch_description():demo_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_tf2_py'),'launch'),'/turtle_tf2_demo_launch.py']),)returnLaunchDescription([demo_nodes,Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',),])

Language: unknown


key: chroma:document
string_value:
Language: unknown

Node(package='learning_tf2_py',executable='fixed_frame_tf2_broadcaster',name='fixed_broadcaster',),

Language: unknown

rosdep install

i -

from

path src -

rosdistro jazzy

y

Language: unknown

colcon build -

packages

select learning_tf2_py

Language: unknown

colcon build -

packages

select learning_tf2_py

Language: unknown

colcon build -

merge

install -

packages

select learning_tf2_py

Language: unknown

. install/setup.bash

Language: unknown

. install/setup.bash

Language: unknown

#CMDcall install\setup.bat#Powershell.\install\setup.ps1

Language: unknown

ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo_launch.py

Language: unknown ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo_launch.py target_frame:=carrot1

Language: unknown

defgenerate_launch_description():demo_nodes=IncludeLaunchDescription(...,launch_arguments={'target_frame':'carrot1'}.items(),)

Language: unknown


key: chroma:document
string_value:
Language: unknown

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py

Language: unknown

wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py

Language: unknown

curl

sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py

o dynamic_frame_tf2_broadcaster.py

Language: unknown

curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py

o dynamic_frame_tf2_broadcaster.py

Language: unknown


key: chroma:document
string_value:
o dynamic_frame_tf2_broadcaster.py

Language: unknown

importmathfromgeometry_msgs.msgimportTransformStampedimportrclpyfromrclpy.nodeimportNodefromtf2_rosimportTransformBroadcasterclassDynamicFrameBroadcaster(Node):def__init__(self):super().__init__('dynamic_frame_tf2_broadcaster')self.tf_broadcaster=TransformBroadcaster(self)self.timer=self.create_timer(0.1,self.broadcast_timer_callback)defbroadcast_timer_callback(self):seconds,_=self.get_clock().now().seconds_nanoseconds()x=seconds

math.pit=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='turtle1't.child_frame_id='carrot1't.transform.translation.x=10

math.sin(x)t.transform.translation.y=10

math.cos(x)t.transform.translation.z=0.0t.transform.rotation.x=0.0t.transform.rotation.y=0.0t.transform.rotation.z=0.0t.transform.rotation.w=1.0self.tf_broadcaster.sendTransform(t)defmain():rclpy.init()node=DynamicFrameBroadcaster()try:rclpy.spin(node)exceptKeyboardInterrupt:passrclpy.shutdown()

Language: unknown


key: chroma:document
string_value:
Language: unknown

seconds,_=self.get_clock().now().seconds_nanoseconds()x=seconds

math.pi...t.transform.translation.x=10

math.sin(x)t.transform.translation.y=10

math.cos(x)

Language: unknown

'dynamic_frame_tf2_broadcaster = learning_tf2_py.dynamic_frame_tf2_broadcaster:main',

Language: unknown

importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcefromlaunch_ros.actionsimportNodedefgenerate_launch_description():demo_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_tf2_py'),'launch'),'/turtle_tf2_demo_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)returnLaunchDescription([demo_nodes,Node(package='learning_tf2_py',executable='dynamic_frame_tf2_broadcaster',name='dynamic_broadcaster',),])

Language: unknown

rosdep install

i -

from

path src -


key: chroma:document
string_value:
Language: unknown

rosdep install

i -

from

path src -

rosdistro jazzy

y

Language: unknown

colcon build -

packages

select learning_tf2_py

Language: unknown

colcon build -

packages

select learning_tf2_py

Language: unknown

colcon build -

merge

install -

packages

select learning_tf2_py

Language: unknown

. install/setup.bash

Language: unknown

. install/setup.bash

Language: unknown

#CMDcall install\setup.bat#Powershell.\install\setup.ps1

Language: unknown

ros2 launch learning_tf2_py turtle_tf2_dynamic_frame_demo_launch.py


key: chroma:document
string_value:
Title: Ensuring security across machines URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Security/Security-on-Two.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Ensuring security across machinesGoal:Make two different machines communicate securely.Tutorial level:AdvancedTime:5 minutesContentsBackgroundCreate the second keystoreCopy filesLaunch the nodesBackgroundBefore proceeding ensure you have completed theSetting up securitytutorial.The previous tutorials have used two ROS nodes on the same machine sending all network communications over the localhost interface. Let’s extend that scenario to involve multiple machines, since the benefits of authentication and encryption then become more obvious.Suppose that the machine with the keystore created in the previous demo has a hostnameAlice, and that we want to also use another machine with hostnameBobfor our multi-machinetalker/listenerdemo. We need to move some keys fromAlicetoBobto allow SROS 2 to authenticate and encrypt the transmissions.Create the second keystoreBegin by creating an empty keystore onBob; the keystore is actually just an empty directory:LinuxMacOSWindowssshBob mkdir~/sros2_demoexitsshBob


key: chroma:document
string_value:
directory:LinuxMacOSWindowssshBob mkdir~/sros2_demoexitsshBob mkdir~/sros2_demoexitssh BobmdC:\dev\ros2\sros2_demoexitCopy filesNext copy the keys and certificates for thetalkerprogram fromAlicetoBob. Since the keys are just text files, we can usescpto copy them.LinuxMacOSWindowscd~/sros2_demo/demo_keystore scp-rtalkerUSERNAME@Bob:~/sros2_demo/demo_keystorecd~/sros2_demo/demo_keystore scp-rtalkerUSERNAME@Bob:~/sros2_demo/demo_keystorecdC:\dev\ros2\sros2_demo\demo_keystore scp -r talker USERNAME@Bob:/dev/ros2/sros2_demo/demo_keystoreWarningNote that in this case the entire keystore is shared across the different machines which may not be the desired behavior, as it may result in a security risk. Please refer toDeployment Guidelinesfor more information in this regard.That will be very quick, since it’s just copying some very small text files. Now, we’re ready to run a multi-machine talker/listener demo!Launch the nodesOnce the environment is set up, run the talker


key: chroma:document
string_value:
the nodesOnce the environment is set up, run the talker onBob:ros2rundemo_nodes_cpptalker--ros-args--enclave/talker_listener/talkerand launch the listener onAlice:ros2rundemo_nodes_pylistener--ros-args--enclave/talker_listener/listenerAlice will now be receiving encrypted messages from Bob.With two machines successfully communicating using both encryption and authentication, you can use the same procedure to add more machines to your ROS graph.


key: chroma:document
string_value:
Code Examples:

Language: unknown

sshBob

mkdir~/sros2_demoexit

Language: unknown

sshBob

mkdir~/sros2_demoexit

Language: unknown

ssh BobmdC:\dev\ros2\sros2_demoexit

Language: unknown

cd~/sros2_demo/demo_keystore

scp

rtalkerUSERNAME@Bob:~/sros2_demo/demo_keystore

Language: unknown

cd~/sros2_demo/demo_keystore

scp

rtalkerUSERNAME@Bob:~/sros2_demo/demo_keystore

Language: unknown

cdC:\dev\ros2\sros2_demo\demo_keystore

scp

r talker USERNAME@Bob:/dev/ros2/sros2_demo/demo_keystore

Language: unknown

ros2rundemo_nodes_cpptalker-

ros

args-

enclave/talker_listener/talker

Language: unknown

ros2rundemo_nodes_pylistener-

ros

args-

enclave/talker_listener/listener


key: chroma:document
string_value:
Title: GurumNetworks GurumDDS

URL: https://docs.ros.org/en/jazzy/Installation/DDS

Implementations/Working

with

GurumNetworks

GurumDDS.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
GurumNetworks GurumDDSrmw_gurumddsis an implementation of the ROS middleware interface using GurumNetworks GurumDDS. For more information about GurumDDS, visit theGurumNetworks website.PrerequisitesThis guide assumes you have completed the ROS 2 environment setup process, either byInstalling ROS 2 via Deb PackagesorBuilding ROS 2 from source on Ubuntu.Version Requirements (see the README for details):ROS 2 DistroGurumDDS Versionrolling>= 3.2.0jazzy>= 3.2.0humble3.1.xDeb packages of GurumDDS are provided in the ROS 2 apt repositories on Ubuntu. Windows binary installer of GurumDDS will be available soon.You can obtain a free trial license from theGurumDDS Free Trial page.After acquiring a license, place it in the following location:/etc/gurumnetInstallationOption 1: Install from the ROS 2 apt repository (Recommended)sudoaptinstallros-jazzy-rmw-gurumdds-cppThis installs bothrmw_gurumdds_cppandgurumdds.Option 2: Build from source codeClone the repositorycdros2_ws/src


key: chroma:document
string_value:
2: Build from source codeClone the repositorycdros2_ws/src gitclonehttps://github.com/ros2/rmw_gurumdds-bjazzyros2/rmw_gurumddsInstall dependencies:cd.. rosdepinstall--fromsrc-i--rosdistrojazzyBuild the worksapce using Colcon:colconbuild--symlink-installSwitch to rmw_gurumddsSwitch from other RMW implementations to rmw_gurumdds by setting the environment variable:exportRMW_IMPLEMENTATION=rmw_gurumdds_cppFor more information on working with multiple RMW implementations, seeWorking with multiple RMW implementations.Testing the installationRun thetalkerandlistenernodes to verify your installation:ros2rundemo_nodes_cpptalkerros2rundemo_nodes_cpplistenerIf the nodes communicate successfully, your installation is working correctly.NoteRemember to source your ROS 2 setup script before running these commands.


key: chroma:document
string_value:
Code Examples:

Language: unknown

sudoaptinstallros

jazzy

rmw

gurumdds

cpp

Language: unknown

cdros2_ws/src

gitclonehttps://github.com/ros2/rmw_gurumdds

bjazzyros2/rmw_gurumdds

Language: unknown

cd..

rosdepinstall-

fromsrc

i-

rosdistrojazzy

Language: unknown

colconbuild-

symlink

install

Language: unknown

exportRMW_IMPLEMENTATION=rmw_gurumdds_cpp

Language: unknown

ros2rundemo_nodes_cpptalker

Language: unknown

ros2rundemo_nodes_cpplistener


key: chroma:document
string_value:
Title: Contributing to ROS 2 Documentation URL: https://docs.ros.org/en/jazzy/The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Contributing to ROS 2 DocumentationTable of ContentsBranch structureSource structureBuilding the site locallyBuilding the site for one branchView Site Through Github CIBuilding the site for all branchesChecking for broken linksMigrating Pages from the ROS WikiMigrating a Wiki FileBuilding the Site with GitHub CodespacesBuilding the Site with DevcontainerWriting pagesTable of ContentsHeadingsListsCode FormattingImagesReferences and LinksContributions to this site are most welcome. This page explains how to contribute to ROS 2 Documentation. Please be sure to read the below sections carefully before contributing.The site is built usingSphinx, and more particularly usingSphinx multiversion.Branch structureThe source code of documentation is located in theROS 2 Documentation GitHub repository. This repository is set up with one branch per ROS 2 distribution to handle differences between the distributions. If a change is common to all ROS 2 distributions, it should be made to therollingbranch (and then will be


key: chroma:document
string_value:
it should be made to therollingbranch (and then will be backported as appropriate). If a change is specific to a particular ROS 2 distribution, it should be made to the respective branch.Source structureThe source files for the site are all located under thesourcesubdirectory. Templates for various sphinx plugins are located undersource/_templates. The root directory contains configuration and files required to locally build the site for testing.Building the site locallyStart by creatingvenvto build the documentation:#activatethevenvpython3 -m venv ros2doc#activatevenvsource ros2doc/bin/activateAnd install requirements located in therequirements.txtfile:LinuxmacOSWindowspip install -r requirements.txt -c constraints.txtpip install -r requirements.txt -c constraints.txtpython -m pip install -r requirements.txt -c constraints.txtIn order for Sphinx to be able to generate diagrams, thedotcommand must be available.LinuxmacOSWindowssudo apt update ; sudo apt install graphvizbrew install graphvizDownload an


key: chroma:document
string_value:
; sudo apt install graphvizbrew install graphvizDownload an installer fromthe Graphviz Download pageand install it. Make sure to allow the installer to add it to the Windows%PATH%, otherwise Sphinx will not be able to find it.Building the site for one branchTo build the site for just this branch, typemakehtmlat the top-level of the repository. This is the recommended way to test out local changes.make htmlThe build process can take some time. To see the output, openbuild/html/index.htmlin your browser.You can also run the documentation tests locally (usingdoc8) with the following command:make testView Site Through Github CIFor small changes to the ROS 2 Docs you can view your changes as rendered HTML using artifacts generated in our Github Actions. The “build” action produces the entire ROS Docs as a downloadable Zip file that contains all HTML fordocs.ros.orgThis build action is triggered after passing the test action and lint action.To download and view your changes first go to your pull request and


key: chroma:document
string_value:
and view your changes first go to your pull request and under the title click the “Checks” tab. On the left hand side of the checks page, click on the “Test” section under the “tests” section  click on “build” dialog. This will open a menu on the right, where you can click on “Upload document artifacts” and scroll to the bottom to see the download link for the Zipped’ HTML files under the heading “Artifact download URL”.Building the site for all branchesTo build the site for all branches, typemakemultiversionfrom therollingbranch. This has two drawbacks:The multiversion plugin doesn’t understand how to do incremental builds, so it always rebuilds everything. This can be slow.When typingmakemultiversion, it will always check out exactly the branches listed in theconf.pyfile. That means that local changes will not be shown.To show local changes in the multiversion output, you must first commit the changes to a local branch. Then you must edit theconf.pyfile and change thesmv_branch_whitelistvariable to point


key: chroma:document
string_value:
and change thesmv_branch_whitelistvariable to point to your branch.Checking for broken linksTo check for broken links on the site, run:make linkcheckThis will check the entire site for broken links, and output the results to the screen andbuild/linkcheck.Migrating Pages from the ROS WikiThe first step in migrating a page from theROS Wikito the ROS 2 documentation is to determine if the page needs to be migrated. Check if the content, or something similar, is available onhttps://docs.ros.org/en/rollingby searching for related terms. If it has already been migrated, congratulations! You are done. If it hasn’t been migrated, then consider whether it is worth keeping. Pages that you or others find useful, and refer to regularly, are good candidates assuming they have not been superseded by other documentation. Pages for ROS projects and features that are no longer supported by a current distribution should not be migrated.The next step for migrating a ROS Wiki page is to determine the correct location for the


key: chroma:document
string_value:
a ROS Wiki page is to determine the correct location for the migrated page. Only ROS Wiki pages that cover core ROS concepts belong in the ROS Documentation, these pages should be migrated to a logical location within the ROS documentation. Package specific documentation should be migrated to the package-level documentation generated in the package’s source repository. Once the package level documentation has been updated it will be visibleas part of the package-level documentation. If you are unsure whether and where to migrate a page, please get in touch via an issue onhttps://github.com/ros2/ros2_documentationor onhttps://discourse.ros.org.Once you’ve determined that a ROS Wiki page is worth migrating, and found an appropriate landing spot in the ROS documentation, the next step in the migration process is to set up the conversion tools necessary to migrate the page. In most cases the only tools necessary to migrate a single ROS Wiki page to the ROS Docs are thePanDoccommand line tool and a text editor.


key: chroma:document
string_value:
the ROS Docs are thePanDoccommand line tool and a text editor. PanDoc is supported by most modern operating systems using the installation instruction found on their website. It is worth noting that the ROS Wiki uses an older wiki technology (MoinMoin), so the markup language used is an obscure dialect of theMediaWikiformat. We’ve found that the easiest way to migrate a page from the ROS Wiki is to convert it from HTML into reStructured text using PanDoc.Migrating a Wiki FileClone the appropriate repository.  If you are migrating a page to the official documentation hosted here, then you should clonehttps://github.com/ros2/ros2_documentation.Create a new Github branch for your migrated page. We suggest something likepagename-migration.Download the appropriate ROS Wiki page to an html file using wget or a similar tool (e.g.wget-Ourdf.htmlhttps://wiki.ros.org/urdf). Alternatively you can use your web browser to save the page’s HTML.Next you need to remove the extraneous HTML in the file you downloaded Using


key: chroma:document
string_value:
to remove the extraneous HTML in the file you downloaded Using your browser’s developer mode, find the name of the first useful HTML element in the Wiki page. In most cases all of the HTML between the third line of the file, starting with the<head>tag, through the start of the first<h1>tag can be safely removed. In the case where there is a table of contents, the first useful tag may be an<h2>tag.  Similarly, the ROS wiki contains some footer text that starts with<divid="pagebottom"></div>and ends just above</body></html>that can also be removed.Convert your html file by running a PanDoc conversion between HTML and restructured text. The following command coverts an HTML file to the equivalent reStructured text files:pandoc-fhtml-trsturdf.html>URDF.rst.Attempt to build your new documentation using themakehtmlcommand. There may be errors and warnings that you will need to address.CAREFULLYread through the entire page making sure the material is up to date for ROS 2. Check every single link to make sure it


key: chroma:document
string_value:
up to date for ROS 2. Check every single link to make sure it points to the appropriate location on docs.ros.org. Internal document references must be updated to point to the equivalent ROS 2 material. Your updated document should not point to the ROS Wiki unless it is absolutely necessary. This process may require you alter the document considerably, and you may need to pull multiple wiki files. You should verify that every code sample in the document is working correctly under ROS 2.Find and download any images that may be in the old document. The easiest way to do this is to right click in the browser and download all of the images. Alternatively you can find images by searching for<imgsrc>tags in the HTML file.For each image files downloaded update the image file links to point to the correct image directory for the ROS Docs. If any of the images require updating, or could be replaced with aMermaidchart, please make this change. Be aware that Mermaid.js is only supported in the core ROS 2 documenation


key: chroma:document
string_value:
Mermaid.js is only supported in the core ROS 2 documenation currently.Once your document is complete add a table of contents to the top of your new rst document using the appropriate Sphinx commands. This block should replace any existing table of contents from the old ROS Wiki.Issue your pull request. Make sure to point to the original ROS Wiki file for reference.Once your pull request has been accepted please add a note to the top of the page on the original ROS Wiki article pointing to the new documentation page.For a real-world example of this process in action, please refer to the ROS 2 Image Processing Pipeline in boththe ROS 2 Docsand in the originalROS Wiki. The completed documentation page can be found in theROS 2 package documentation for image_pipeline.Building the Site with GitHub CodespacesFirst, you need to have a GitHub account (if you don’t have one, you can create one for free). Then, you need to go to theROS 2 Documentation GitHub repository. After that, you can open the repository in


key: chroma:document
string_value:
GitHub repository. After that, you can open the repository in Codespaces, it can be done just by clicking on the “Code” button on the repository page, then choose “Open with Codespaces” from the dropdown menu.After that, you will be redirected to your Codespaces page, where you can see the progress of the Codespaces creation. Once it is done, a Visual Studio Code tab will be opened in your browser. You can open the terminal by clicking on the “Terminal” tab in the top panel or by pressingCtrl-J.In this terminal, you can run any command you want, for example, you can run the following command to build the site for just this branch:make htmlFinally, to view the site, you can click on the “Go Live” button in the right bottom panel and then, it will open the site in a new tab in your browser (you will need to browse to thebuild/htmlfolder).Building the Site with DevcontainerROS 2 Documentation GitHub repositoryalso supportsDevcontainerdevelopment environment with Visual Studio Code. This will enable you to


key: chroma:document
string_value:
environment with Visual Studio Code. This will enable you to build the documentation much easier without changing your operating system.SeeSetup ROS 2 with VSCode and Docker [community-contributed]to install VS Code and Docker before the following procedure.Clone repository and start VS Code:git clone https://github.com/ros2/ros2_documentationcd ./ros2_documentationcode .To useDevcontainer, you need to install “Remote Development” Extension within VS Code search in Extensions (CTRL+SHIFT+X) for it.And then, useView->CommandPalette...orCtrl+Shift+Pto open the command palette. Search for the commandDevContainers:ReopeninContainerand execute it. This will build your development docker container for you automatically.To build the documentation, open a terminal usingView->TerminalorCtrl+Shift+`andNewTerminalin VS Code. Inside the terminal, you can build the documentation:make htmlWriting pagesThe ROS 2 documentation website uses thereStructuredTextformat, which is the default plaintext markup language used by


key: chroma:document
string_value:
which is the default plaintext markup language used by Sphinx. This section is a brief introduction toreStructuredTextconcepts, syntax, and best practices.You can refer toreStructuredText User Documentationfor a detailed technical specification.Table of ContentsThere are two types of directives used for the generation of a table of contents,..toctree::and..contents::. The..toctree::is used in top-level pages likeTutorials.rstto set ordering and visibility of its child pages. This directive creates both left navigation panel and in-page navigation links to the child pages listed. It helps readers to understand the structure of separate documentation sections and navigate between pages...toctree:::maxdepth:1The..contents::directive is used for the generation of a table of contents for that particular page. It parses all present headings in a page and builds an in-page nested table of contents. It helps readers to see an overview of the content and navigate inside a page.The..contents::directive supports the


key: chroma:document
string_value:
navigate inside a page.The..contents::directive supports the definition of maximum depth of nested sections. Using:depth:2will only show Sections and Subsections in the table of contents...contents::Table of Contents:depth:2:local:HeadingsThere are four main Heading types used in the documentation. Note that the number of symbols has to match the length of the title.Page Title Header=================Section Header--------------2 Subsection Header^^^^^^^^^^^^^^^^^^^2.4 Subsubsection Header~~~~~~~~~~~~~~~~~~~~~~~~We usually use one digit for numbering subsections and two digits (dot separated) for numbering subsubsections in Tutorials and How-To-Guides.ListsStars*are used for listing unordered items with bullet points and number sign#.is used for listing numbered items. Both of them support nested definitions and will render accordingly.*bullet point*bullet point nested*bullet point nested*bullet point#.first listed item#.second lited itemCode FormattingIn-text code can be formatted usingbackticksfor


key: chroma:document
string_value:
FormattingIn-text code can be formatted usingbackticksfor showinghighlightedcode.In-text code can be formatted using``backticks``for showing``highlighted``code.Code blocks inside a page need to be captured using..code-block::directive...code-block::supports code highlighting for syntaxes likeC++,YAML,console,bash, and more. Code inside the directive needs to be indented...code-block::C++intmain(intargc,char**argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<ParametersClass>());rclcpp::shutdown();return0;}ImagesImages can be inserted using the..image::directive...image::images/turtlesim_follow1.pngReferences and LinksExternal linksThe syntax of creating links to external web pages is shown below.`ROS Docs<https://docs.ros.org>`_The above link will appear asROS Docs. Note the underscore after the final single quote.Internal linksThe:doc:directive is used to create in-text links to other pages.:doc:`Quality of Service <../Tutorials/Quality-of-Service>`Note that the relative path to the file is


key: chroma:document
string_value:
that the relative path to the file is used.Therefdirective is used to make links to specific parts of a page. These could be headings, images or code sections inside the current or different page.Definition of explicit target right before the desired object is required. In the example below, the target is defined as_talker-listenerone line before the headingTrysomeexamples..._talker-listener:Try some examples-----------------Now the link from any page in the documentation to that header can be created.:ref:`talker-listener demo <talker-listener>`This link will navigate a reader to the target page with an HTML anchor link#talker-listener.MacrosMacros can be used to simplify writing documentation that targets multiple distributions.Use a macro by including the macro name in curly braces. For example, when generating the docs for Rolling on therollingbranch:UseBecomes (for Rolling)Example{DISTRO}rollingros-{DISTRO}-pkg{DISTRO_TITLE}RollingROS 2 {DISTRO_TITLE}{DISTRO_TITLE_FULL}Rolling RidleyROS 2


key: chroma:document
string_value:
2 {DISTRO_TITLE}{DISTRO_TITLE_FULL}Rolling RidleyROS 2 {DISTRO_TITLE_FULL}{REPOS_FILE_BRANCH}rollinggit checkout {REPOS_FILE_BRANCH}The same file can be used on multiple branches (i.e., for multiple distros) and the generated content will be distro-specific.


key: chroma:document
string_value:
Code Examples:

Language: unknown

#activatethevenvpython3

m venv ros2doc#activatevenvsource ros2doc/bin/activate

Language: unknown

pip install

r requirements.txt

c constraints.txt

Language: unknown

pip install

r requirements.txt

c constraints.txt

Language: unknown

python

m pip install

r requirements.txt

c constraints.txt

Language: unknown sudo apt update ; sudo apt install graphviz

Language: unknown

brew install graphviz

Language: unknown

make html

Language: unknown

make test

Language: unknown

make linkcheck

Language: unknown

make html

Language: unknown git clone https://github.com/ros2/ros2_documentationcd ./ros2_documentationcode .

Language: unknown

make html

Language: unknown

..toctree:::maxdepth:1

Language: unknown

..contents::Table of Contents:depth:2:local:

Language: unknown Page Title Header=================Section Header--------------2 Subsection Header^^^^^^^^^^^^^^^^^^^2.4 Subsubsection Header~~~~~~~~~~~~~~~~~~~~~~~~

Language: unknown

bullet point


key: chroma:document
string_value:
Language: unknown

bullet point

bullet point nested

bullet point nested

bullet point

Language: unknown #.first listed item#.second lited item

Language: unknown In-text code can be formatted using``backticks``for showing``highlighted``code.

Language: unknown

..code

block::C++intmain(intargc,char*

argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<ParametersClass>());rclcpp::shutdown();return0;}

Language: unknown

..image::images/turtlesim_follow1.png

Language: unknown

`ROS Docs<https://docs.ros.org>`_

Language: unknown

:doc:`Quality of Service <../Tutorials/Quality

of

Service>`

Language: unknown

.._talker

listener:Try some examples-----------------

Language: unknown

:ref:`talker

listener demo <talker

listener>`


key: chroma:document
string_value:
Title: Alternatives

URL: https://docs.ros.org/en/jazzy/Installation/Alternatives.html

Section: Installation

--------------------------------------------------------------------------------

AlternativesA list of alternative ways to install ROS 2 – whether it’s by building from source or installing a binary.Ubuntu (source)Ubuntu (binary)Windows (source)RHEL (source)RHEL (binary)macOS (source)Latest development (source)


key: chroma:document
string_value:
Title: Metrics

URL: https://docs.ros.org/en/jazzy/The

ROS2

Project/Metrics.html

Section: Installation

--------------------------------------------------------------------------------

MetricsTable of ContentsMetrics.ros.orgPeriodic Metrics ReportHistorical Metrics ReportsWe measure aspects of the ROS community to understand and track the impact of our work and identify areas for improvement. We take inspiration from the MeeGo Project’s metrics.Metrics.ros.orgAtmetrics.ros.orgyou can find many visualizations of metrics about ROS.Periodic Metrics ReportWe periodically publish a metrics report that provides a quantitative view of the ROS community. We’re collectively learning what to measure and how and evoloving as systems change. Please provide feedback! Add your suggestions on how to improve these reports by posting them toROS Discourse Site Feedback Category.Historical Metrics Reports2023202220212020201920182017201620152014201320122011


key: chroma:document
string_value:
Title: Building ROS 2 with tracing URL: https://docs.ros.org/en/jazzy/How-To-Guides/Building-ROS-2-with-Tracing.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Building ROS 2 with tracingTable of ContentsPrerequisitesBuild configurationsBuilding without tracepointsBuilding without instrumentationValidatingTracing instrumentation is included in the ROS 2 source code, and Linux installations of ROS 2 include the LTTng tracer as a dependency. Therefore, ROS 2 can be traced out-of-the-box on Linux.However, ROS 2 can be built from source to remove the tracepoints or completely remove the instrumentation. This guide shows how to do that. For more information, seethe repository.NoteThis guide only applies to Linux systems.PrerequisitesSet up your system to build ROS 2 from source. Seethe source installation pagefor more information.Build configurationsThe ROS 2 tracing instrumentation is split into two components: function instrumentation and tracepoints. First, a ROS 2 core package (e.g.,rclcpp) calls a function provided by thetracetoolspackage. Then, that function triggers a tracepoint, which records data if the tracepoint is enabled at runtime.By default, if the


key: chroma:document
string_value:
data if the tracepoint is enabled at runtime.By default, if the tracer is notconfigured to trace or if the tracepoints are not enabled, they will have virtually no impact on the execution. However, the tracepoints can still be removed through a CMake option. Furthermore, the functions can be completely removed through a CMake option, which implies that tracepoints are also removed.Building without tracepointsThis step depends on whether you arebuilding ROS 2 from sourceor using ROS 2 binaries (deb packagesorbinary archive). To remove the tracepoints, (re)buildtracetoolsand set theTRACETOOLS_TRACEPOINTS_EXCLUDEDCMake option toON:Source installationBinary installationcd~/ros2_jazzy colconbuild--packages-selecttracetools--cmake-clean-cache--cmake-args-DTRACETOOLS_TRACEPOINTS_EXCLUDED=ONClone theros2_tracingrepository into your workspace and build:cd~/ws gitclonehttps://github.com/ros2/ros2_tracing.git-bjazzysrc/ros2_tracing


key: chroma:document
string_value:
colconbuild--packages-selecttracetools--cmake-args-DTRACETOOLS_TRACEPOINTS_EXCLUDED=ONBuilding without instrumentationTo completely remove both tracepoints and function calls,build ROS 2 from sourceand set theTRACETOOLS_DISABLEDCMake option toON:cd~/ros2_jazzy colconbuild--cmake-args-DTRACETOOLS_DISABLED=ON--no-warn-unused-cliValidatingValidate that tracing is disabled:cd~/wssourceinstall/setup.bash ros2runtracetoolsstatusIt should print out:Without tracepointsWithout instrumentationTracingdisabledTracingdisabledthroughconfigurationIf something else is printed, then something went wrong.


key: chroma:document
string_value:
Code Examples:

Language: unknown

cd~/ros2_jazzy

colconbuild-

packages

selecttracetools-

cmake

clean

cache-

cmake

args

DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON

Language: unknown

cd~/ws

gitclonehttps://github.com/ros2/ros2_tracing.git

bjazzysrc/ros2_tracing

colconbuild-

packages

selecttracetools-

cmake

args

DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON

Language: unknown

cd~/ros2_jazzy

colconbuild-

cmake

args

DTRACETOOLS_DISABLED=ON-

no

warn

unused

cli

Language: unknown

cd~/wssourceinstall/setup.bash

ros2runtracetoolsstatus

Language: unknown

Tracingdisabled

Language: unknown

Tracingdisabledthroughconfiguration


key: chroma:document
string_value:
Title: Creating a content filtering subscription URL: https://docs.ros.org/en/jazzy/Tutorials/Demos/Content-Filtering-Subscription.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Creating a content filtering subscriptionGoal:Create a content filtering subscription.Tutorial level:AdvancedTime:15 minutesTable of ContentsOverviewRMW SupportInstalling the demoTemperature filtering demoRelated contentOverviewROS 2 applications typically consist of topics to transmit data from publishers to subscriptions. Basically, subscriptions receive all published data from publishers on the topic. But sometimes, a subscription might be interested in only a subset of the data which is being sent by publishers. A content filtering subscription allows to receive only the data of interest for the application.In this demo, we’ll be highlighting how to create a content filtering subscription and how they work.RMW SupportContent filtering subscriptions require RMW implementation support.Content-Filtering-Subscription Support Statusrmw_fastrtpssupportedrmw_connextddssupportedrmw_cycloneddsnot supportedCurrently all RMW implementations that support content filtering subscriptions areDDSbased. That means


key: chroma:document
string_value:
support content filtering subscriptions areDDSbased. That means that the supported filtering expressions and parameters are also dependent onDDS, you can refer toDDS specificationAnnexB-SyntaxforQueriesandFiltersfor details.Installing the demoSee theinstallation instructionsfor details on installing ROS 2.If you’ve installed ROS 2 from packages, ensure that you haveros-jazzy-demo-nodes-cppinstalled. If you downloaded the archive or built ROS 2 from source, it will already be part of the installation.Temperature filtering demoThis demo shows how a content filtering subscription can be used to only receive temperature values that are out of the acceptable temperature range, detecting emergencies. The content filtering subscription filters out the uninteresting temperature data, so that the subscription callback is not


key: chroma:document
string_value:
temperature data, so that the subscription callback is not issued.ContentFilteringPublisher:https://github.com/ros2/demos/blob/jazzy/demo_nodes_cpp/src/topics/content_filtering_publisher.cpp#include<chrono>#include<cstdio>#include<memory>#include<utility>#include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"std_msgs/msg/float32.hpp"#include"demo_nodes_cpp/visibility_control.h"usingnamespacestd::chrono_literals;namespacedemo_nodes_cpp{// The simulated temperature data starts from -100.0 and ends at 150.0 with a step size of 10.0constexprstd::array<float,3>TEMPERATURE_SETTING{-100.0f,150.0f,10.0f};// Create a ContentFilteringPublisher class that subclasses the generic rclcpp::Node base class.// The main function below will instantiate the class as a ROS node.classContentFilteringPublisher:publicrclcpp::Node{public:DEMO_NODES_CPP_PUBLICexplicitContentFilteringPublisher(constrclcpp::NodeOptions&options):Node("content_filtering_publisher",options){// Create a function for when


key: chroma:document
string_value:
Create a function for when messages are to be sent.setvbuf(stdout,NULL,_IONBF,BUFSIZ);autopublish_message=[this]()->void{msg_=std::make_unique<std_msgs::msg::Float32>();msg_->data=temperature_;temperature_+=TEMPERATURE_SETTING[2];if(temperature_>TEMPERATURE_SETTING[1]){temperature_=TEMPERATURE_SETTING[0];}RCLCPP_INFO(this->get_logger(),"Publishing: '%f'",msg_->data);// Put the message into a queue to be processed by the middleware.// This call is non-blocking.pub_->publish(std::move(msg_));};// Create a publisher with a custom Quality of Service profile.// Uniform initialization is suggested so it can be trivially changed to// rclcpp::KeepAll{} if the user wishes.// (rclcpp::KeepLast(7) -> rclcpp::KeepAll() fails to compile)rclcpp::QoSqos(rclcpp::KeepLast{7});pub_=this->create_publisher<std_msgs::msg::Float32>("temperature",qos);// Use a timer to schedule periodic message


key: chroma:document
string_value:
Use a timer to schedule periodic message publishing.timer_=this->create_wall_timer(1s,publish_message);}private:floattemperature_=TEMPERATURE_SETTING[0];std::unique_ptr<std_msgs::msg::Float32>msg_;rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtrpub_;rclcpp::TimerBase::SharedPtrtimer_;};}// namespace demo_nodes_cppThe content filter is defined in the subscription side, publishers don’t need to be configured in any special way to allow content filtering. TheContentFilteringPublishernode publishes simulated temperature data starting from -100.0 and ending at 150.0 with a step size of 10.0 every second.We can run the demo by running theros2rundemo_nodes_cppcontent_filtering_publisherexecutable (don’t forget to source the setup file


key: chroma:document
string_value:
first):$ros2rundemo_nodes_cppcontent_filtering_publisher[INFO][1651094594.822753479][content_filtering_publisher]:Publishing:'-100.000000'[INFO][1651094595.822723857][content_filtering_publisher]:Publishing:'-90.000000'[INFO][1651094596.822752996][content_filtering_publisher]:Publishing:'-80.000000'[INFO][1651094597.822752475][content_filtering_publisher]:Publishing:'-70.000000'[INFO][1651094598.822721485][content_filtering_publisher]:Publishing:'-60.000000'[INFO][1651094599.822696188][content_filtering_publisher]:Publishing:'-50.000000'[INFO][1651094600.822699217][content_filtering_publisher]:Publishing:'-40.000000'[INFO][1651094601.822744113][content_filtering_publisher]:Publishing:'-30.000000'[INFO][1651094602.822694805][content_filtering_publisher]:Publishing:'-20.000000'[INFO][1651094603.822735805][content_filtering_publisher]:Publishing:'-10.000000'[INFO][1651094604.822722094][content_filtering_publisher]:Publishing:'0.000000'[INFO][1651094605.822699960][content_filtering_publisher]:Publishing:'10.0000


key: chroma:document
string_value:
4605.822699960][content_filtering_publisher]:Publishing:'10.000000'[INFO][1651094606.822748946][content_filtering_publisher]:Publishing:'20.000000'[INFO][1651094607.822694017][content_filtering_publisher]:Publishing:'30.000000'[INFO][1651094608.822708798][content_filtering_publisher]:Publishing:'40.000000'[INFO][1651094609.822692417][content_filtering_publisher]:Publishing:'50.000000'[INFO][1651094610.822696426][content_filtering_publisher]:Publishing:'60.000000'[INFO][1651094611.822751913][content_filtering_publisher]:Publishing:'70.000000'[INFO][1651094612.822692231][content_filtering_publisher]:Publishing:'80.000000'[INFO][1651094613.822745549][content_filtering_publisher]:Publishing:'90.000000'[INFO][1651094614.822701982][content_filtering_publisher]:Publishing:'100.000000'[INFO][1651094615.822691465][content_filtering_publisher]:Publishing:'110.000000'[INFO][1651094616.822649070][content_filtering_publisher]:Publishing:'120.000000'[INFO][1651094617.822693616][content_filtering_publisher]:Publishing:'130.


key: chroma:document
string_value:
1094617.822693616][content_filtering_publisher]:Publishing:'130.000000'[INFO][1651094618.822691832][content_filtering_publisher]:Publishing:'140.000000'[INFO][1651094619.822688452][content_filtering_publisher]:Publishing:'150.000000'[INFO][1651094620.822645327][content_filtering_publisher]:Publishing:'-100.000000'[INFO][1651094621.822689219][content_filtering_publisher]:Publishing:'-90.000000'[INFO][1651094622.822694292][content_filtering_publisher]:Publishing:'-80.000000'[...]ContentFilteringSubscriber:https://github.com/ros2/demos/blob/jazzy/demo_nodes_cpp/src/topics/content_filtering_subscriber.cpp#include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"rcpputils/join.hpp"#include"std_msgs/msg/float32.hpp"#include"demo_nodes_cpp/visibility_control.h"namespacedemo_nodes_cpp{//


key: chroma:document
string_value:
Emergency temperature data less than -30 or greater than 100constexprstd::array<float,2>EMERGENCY_TEMPERATURE{-30.0f,100.0f};// Create a ContentFilteringSubscriber class that subclasses the generic rclcpp::Node base class.// The main function below will instantiate the class as a ROS node.classContentFilteringSubscriber:publicrclcpp::Node{public:DEMO_NODES_CPP_PUBLICexplicitContentFilteringSubscriber(constrclcpp::NodeOptions&options):Node("content_filtering_subscriber",options){setvbuf(stdout,NULL,_IONBF,BUFSIZ);// Create a callback function for when messages are received.autocallback=[this](conststd_msgs::msg::Float32&msg)->void{if(msg.data<EMERGENCY_TEMPERATURE[0]||msg.data>EMERGENCY_TEMPERATURE[1]){RCLCPP_INFO(this->get_logger(),"I receive an emergency temperature data: [%f]",msg.data);}else{RCLCPP_INFO(this->get_logger(),"I receive a temperature data: [%f]",msg.data);}};// Initialize a subscription with a content filter to receive emergency temperature data that// are less than -30 or greater than


key: chroma:document
string_value:
temperature data that// are less than -30 or greater than 100.rclcpp::SubscriptionOptionssub_options;sub_options.content_filter_options.filter_expression="data < %0 OR data > %1";sub_options.content_filter_options.expression_parameters={std::to_string(EMERGENCY_TEMPERATURE[0]),std::to_string(EMERGENCY_TEMPERATURE[1])};sub_=create_subscription<std_msgs::msg::Float32>("temperature",10,callback,sub_options);if(!sub_->is_cft_enabled()){RCLCPP_WARN(this->get_logger(),"Content filter is not enabled since it's not supported");}else{RCLCPP_INFO(this->get_logger(),"subscribed to topic\"%s\"with content filter options\"%s, {%s}\"",sub_->get_topic_name(),sub_options.content_filter_options.filter_expression.c_str(),rcpputils::join(sub_options.content_filter_options.expression_parameters,", ").c_str());}}private:rclcpp::Subscription<std_msgs::msg::Float32>::SharedPtrsub_;};}// namespace demo_nodes_cppTo enable content filtering, applications can set the filtering expression and the expression parameters


key: chroma:document
string_value:
can set the filtering expression and the expression parameters inSubscriptionOptions. The application can also check if content filtering is enabled on the subscription.In this demo, theContentFilteringSubscribernode creates a content filtering subscription that receives a message only if the temperature value is less than -30.0 or greater than 100.0.As commented before, content filtering subscription support depends on the RMW implementation. Applications can use theis_cft_enabledmethod to check if content filtering is actually enabled on the subscription.To test content filtering subscription, let’s run it:$ros2rundemo_nodes_cppcontent_filtering_subscriber[INFO][1651094590.682660703][content_filtering_subscriber]:subscribedtotopic"/temperature"withcontentfilteroptions"data < %0 OR data > %1, {-30.000000,


key: chroma:document
string_value:
100.000000}"[INFO][1651094594.823805294][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-100.000000][INFO][1651094595.823419993][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-90.000000][INFO][1651094596.823410859][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-80.000000][INFO][1651094597.823350377][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-70.000000][INFO][1651094598.823282657][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-60.000000][INFO][1651094599.823297857][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-50.000000][INFO][1651094600.823355597][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-40.000000][INFO][1651094615.823315377][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[110.000000][INFO][1651094616.823258458][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[120.000000][INFO][1651094617.823323525][content_filtering_subscribe


key: chroma:document
string_value:
.000000][INFO][1651094617.823323525][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[130.000000][INFO][1651094618.823315527][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[140.000000][INFO][1651094619.823331424][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[150.000000][INFO][1651094620.823271748][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-100.000000][INFO][1651094621.823343550][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-90.000000][INFO][1651094622.823286326][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-80.000000][INFO][1651094623.823371031][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-70.000000][INFO][1651094624.823333112][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-60.000000][INFO][1651094625.823266469][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-50.000000][INFO][1651094626.823284093][content_filtering_subscriber]:Ir


key: chroma:document
string_value:
00][INFO][1651094626.823284093][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-40.000000]You


key: chroma:document
string_value:
should see a message showing the content filtering options used and logs for each message received only if the temperature value is less than -30.0 or greater than 100.0.If content filtering is not supported by the RMW implementation, the subscription will still be created without content filtering enabled. We can try that by


key: chroma:document
string_value:
executingRMW_IMPLEMENTATION=rmw_cyclonedds_cppros2rundemo_nodes_cppcontent_filtering_publisher.$RMW_IMPLEMENTATION=rmw_cyclonedds_cppros2rundemo_nodes_cppcontent_filtering_subscriber[WARN][1651096637.893842072][content_filtering_subscriber]:Contentfilterisnotenabledsinceitisnotsupported[INFO][1651096641.246043703][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-100.000000][INFO][1651096642.245833527][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-90.000000][INFO][1651096643.245743471][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-80.000000][INFO][1651096644.245833932][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-70.000000][INFO][1651096645.245916679][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-60.000000][INFO][1651096646.245861895][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-50.000000][INFO][1651096647.245946352][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-40.


key: chroma:document
string_value:
t_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-40.000000][INFO][1651096648.245934569][content_filtering_subscriber]:Ireceiveatemperaturedata:[-30.000000][INFO][1651096649.245877906][content_filtering_subscriber]:Ireceiveatemperaturedata:[-20.000000][INFO][1651096650.245939068][content_filtering_subscriber]:Ireceiveatemperaturedata:[-10.000000][INFO][1651096651.245911450][content_filtering_subscriber]:Ireceiveatemperaturedata:[0.000000][INFO][1651096652.245879830][content_filtering_subscriber]:Ireceiveatemperaturedata:[10.000000][INFO][1651096653.245858329][content_filtering_subscriber]:Ireceiveatemperaturedata:[20.000000][INFO][1651096654.245916370][content_filtering_subscriber]:Ireceiveatemperaturedata:[30.000000][INFO][1651096655.245933741][content_filtering_subscriber]:Ireceiveatemperaturedata:[40.000000][INFO][1651096656.245833975][content_filtering_subscriber]:Ireceiveatemperaturedata:[50.000000][INFO][1651096657.245971483][content_filtering_subscriber]:Ireceiveatemperaturedata:[60.000000]Y


key: chroma:document
string_value:
can see the messageContentfilterisnotenabledbecause underlying RMW implementation does not support the feature, but the demo still successfully creates the normal subscription to receive all temperature data.Related contentcontent filtering examplesthat covers all interfaces for content filtering subscription.content filtering design PR


key: chroma:document
string_value:
Language: unknown #include<chrono>#include<cstdio>#include<memory>#include<utility>#include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"std_msgs/msg/float32.hpp"#include"demo_nodes_cpp/visibility_control.h"usingnamespacestd::chrono_literals;namespacedemo_nodes_cpp{// The simulated temperature data starts from -100.0 and ends at 150.0 with a step size of 10.0constexprstd::array<float,3>TEMPERATURE_SETTING{-100.0f,150.0f,10.0f};// Create a ContentFilteringPublisher class that subclasses the generic rclcpp::Node base class.// The main function below will instantiate the class as a ROS node.classContentFilteringPublisher:publicrclcpp::Node{public:DEMO_NODES_CPP_PUBLICexplicitContentFilteringPublisher(constrclcpp::NodeOptions&options):Node("content_filtering_publisher",options){// Create a function for when messages are to be


key: chroma:document
string_value:
Use a timer to schedule periodic message publishing.timer_=this->create_wall_timer(1s,publish_message);}private:floattemperature_=TEMPERATURE_SETTING[0];std::unique_ptr<std_msgs::msg::Float32>msg_;rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtrpub_;rclcpp::TimerBase::SharedPtrtimer_;};}// namespace demo_nodes_cpp


key: chroma:document
string_value:
Language: unknown

$ros2rundemo_nodes_cppcontent_filtering_publisher[INFO][1651094594.822753479][content_filtering_publisher]:Publishing:'

100.000000'[INFO][1651094595.822723857][content_filtering_publisher]:Publishing:'

90.000000'[INFO][1651094596.822752996][content_filtering_publisher]:Publishing:'

80.000000'[INFO][1651094597.822752475][content_filtering_publisher]:Publishing:'

70.000000'[INFO][1651094598.822721485][content_filtering_publisher]:Publishing:'

60.000000'[INFO][1651094599.822696188][content_filtering_publisher]:Publishing:'

50.000000'[INFO][1651094600.822699217][content_filtering_publisher]:Publishing:'

40.000000'[INFO][1651094601.822744113][content_filtering_publisher]:Publishing:'

30.000000'[INFO][1651094602.822694805][content_filtering_publisher]:Publishing:'

20.000000'[INFO][1651094603.822735805][content_filtering_publisher]:Publishing:'


key: chroma:document
string_value:
10.000000'[INFO][1651094604.822722094][content_filtering_publisher]:Publishing:'0.000000'[INFO][1651094605.822699960][content_filtering_publisher]:Publishing:'10.000000'[INFO][1651094606.822748946][content_filtering_publisher]:Publishing:'20.000000'[INFO][1651094607.822694017][content_filtering_publisher]:Publishing:'30.000000'[INFO][1651094608.822708798][content_filtering_publisher]:Publishing:'40.000000'[INFO][1651094609.822692417][content_filtering_publisher]:Publishing:'50.000000'[INFO][1651094610.822696426][content_filtering_publisher]:Publishing:'60.000000'[INFO][1651094611.822751913][content_filtering_publisher]:Publishing:'70.000000'[INFO][1651094612.822692231][content_filtering_publisher]:Publishing:'80.000000'[INFO][1651094613.822745549][content_filtering_publisher]:Publishing:'90.000000'[INFO][1651094614.822701982][content_filtering_publisher]:Publishing:'100.000000'[INFO][1651094615.822691465][content_filtering_publisher]:Publishing:'110.000000'[INFO][1651094616.822649070][content_filtering_publi


key: chroma:document
string_value:
'110.000000'[INFO][1651094616.822649070][content_filtering_publisher]:Publishing:'120.000000'[INFO][1651094617.822693616][content_filtering_publisher]:Publishing:'130.000000'[INFO][1651094618.822691832][content_filtering_publisher]:Publishing:'140.000000'[INFO][1651094619.822688452][content_filtering_publisher]:Publishing:'150.000000'[INFO][1651094620.822645327][content_filtering_publisher]:Publishing:'


key: chroma:document
string_value:
100.000000'[INFO][1651094621.822689219][content_filtering_publisher]:Publishing:'

90.000000'[INFO][1651094622.822694292][content_filtering_publisher]:Publishing:'

80.000000'[...]


key: chroma:document
string_value:
Language: unknown #include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"rcpputils/join.hpp"#include"std_msgs/msg/float32.hpp"#include"demo_nodes_cpp/visibility_control.h"namespacedemo_nodes_cpp{// Emergency temperature data less than -30 or greater than 100constexprstd::array<float,2>EMERGENCY_TEMPERATURE{-30.0f,100.0f};// Create a ContentFilteringSubscriber class that subclasses the generic rclcpp::Node base class.// The main function below will instantiate the class as a ROS node.classContentFilteringSubscriber:publicrclcpp::Node{public:DEMO_NODES_CPP_PUBLICexplicitContentFilteringSubscriber(constrclcpp::NodeOptions&options):Node("content_filtering_subscriber",options){setvbuf(stdout,NULL,_IONBF,BUFSIZ);// Create a callback function for when messages are received.autocallback=[this](conststd_msgs::msg::Float32&msg)->void{if(msg.data<EMERGENCY_TEMPERATURE[0]||msg.data>EMERGENCY_TEMPERATURE[1]){RCLCPP_INFO(this->get_logger(),"I receive an emergency temperature data:


key: chroma:document
string_value:
receive an emergency temperature data: [%f]",msg.data);}else{RCLCPP_INFO(this->get_logger(),"I receive a temperature data: [%f]",msg.data);}};// Initialize a subscription with a content filter to receive emergency temperature data that// are less than -30 or greater than 100.rclcpp::SubscriptionOptionssub_options;sub_options.content_filter_options.filter_expression="data < %0 OR data > %1";sub_options.content_filter_options.expression_parameters={std::to_string(EMERGENCY_TEMPERATURE[0]),std::to_string(EMERGENCY_TEMPERATURE[1])};sub_=create_subscription<std_msgs::msg::Float32>("temperature",10,callback,sub_options);if(!sub_->is_cft_enabled()){RCLCPP_WARN(this->get_logger(),"Content filter is not enabled since it's not supported");}else{RCLCPP_INFO(this->get_logger(),"subscribed to topic\"%s\"with content filter options\"%s, {%s}\"",sub_->get_topic_name(),sub_options.content_filter_options.filter_expression.c_str(),rcpputils::join(sub_options.content_filter_options.expression_parameters,",


key: chroma:document
string_value:
").c_str());}}private:rclcpp::Subscription<std_msgs::msg::Float32>::SharedPtrsub_;};}// namespace demo_nodes_cpp


key: chroma:document
string_value:
Language: unknown $ros2rundemo_nodes_cppcontent_filtering_subscriber[INFO][1651094590.682660703][content_filtering_subscriber]:subscribedtotopic"/temperature"withcontentfilteroptions"data < %0 OR data > %1, {-30.000000,


key: chroma:document
string_value:
00][INFO][1651094626.823284093][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[-40.000000]


key: chroma:document
string_value:
Language: unknown

$RMW_IMPLEMENTATION=rmw_cyclonedds_cppros2rundemo_nodes_cppcontent_filtering_subscriber[WARN][1651096637.893842072][content_filtering_subscriber]:Contentfilterisnotenabledsinceitisnotsupported[INFO][1651096641.246043703][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

100.000000][INFO][1651096642.245833527][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

90.000000][INFO][1651096643.245743471][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

80.000000][INFO][1651096644.245833932][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

70.000000][INFO][1651096645.245916679][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

60.000000][INFO][1651096646.245861895][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[

50.000000][INFO][1651096647.245946352][content_filtering_subscriber]:Ireceiveanemergencytemperaturedata:[


key: chroma:document
string_value:
40.000000][INFO][1651096648.245934569][content_filtering_subscriber]:Ireceiveatemperaturedata:[

30.000000][INFO][1651096649.245877906][content_filtering_subscriber]:Ireceiveatemperaturedata:[

20.000000][INFO][1651096650.245939068][content_filtering_subscriber]:Ireceiveatemperaturedata:[

10.000000][INFO][1651096651.245911450][content_filtering_subscriber]:Ireceiveatemperaturedata:[0.000000][INFO][1651096652.245879830][content_filtering_subscriber]:Ireceiveatemperaturedata:[10.000000][INFO][1651096653.245858329][content_filtering_subscriber]:Ireceiveatemperaturedata:[20.000000][INFO][1651096654.245916370][content_filtering_subscriber]:Ireceiveatemperaturedata:[30.000000][INFO][1651096655.245933741][content_filtering_subscriber]:Ireceiveatemperaturedata:[40.000000][INFO][1651096656.245833975][content_filtering_subscriber]:Ireceiveatemperaturedata:[50.000000][INFO][1651096657.245971483][content_filtering_subscriber]:Ireceiveatemperaturedata:[60.000000]


key: chroma:document
string_value:
Title: Using theros2paramcommand

line tool

URL: https://docs.ros.org/en/jazzy/How

To

Guides/Using

ros2

param.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Using theros2paramcommand-line toolTable of Contentsros2paramlistros2paramgetros2paramsetros2paramdeleteros2paramdescriberos2paramdumpros2paramloadParameters in ROS 2 can be get, set, listed, and described through a set of services as described inthe concept document. Theros2paramcommand-line tool is a wrapper around these service calls that makes it easy to manipulate parameters from the command-line.ros2paramlistThis command will list all of the available parameters on a given node, or on all discoverable nodes if no node is given.To get all of the parameters on a given node:ros2 param list /my_nodeTo get all of the parameters on all nodes in the system (this can take a long time on a complicated network):ros2 param listros2paramgetThis command will get the value of a particular parameter on a particular node.To get the value of a parameter on a node:ros2 param get /my_node use_sim_timeros2paramsetThis command will set the value of a particular parameter on a particular node. For most parameters, the


key: chroma:document
string_value:
parameter on a particular node. For most parameters, the type of the new value must be the same as the existing type.To set the value of a parameter on a node:ros2 param set /my_node use_sim_time falseThe value that is passed on the command-line is in YAML, which allows arbitrary YAML expressions to be used. However, it also means that certain expressions will be interpreted differently than might be expected. For instance, if the parametermy_stringon nodemy_nodeis of type string, the following will not work:ros2 param set /my_node my_string offThat’s because YAML is interpreting “off” as a boolean, andmy_stringis a string type. This can be worked around by using the YAML syntax for explicitly setting strings, e.g.:ros param set /my_node my_string '!!str off'Additionally, YAML supports heterogeneous lists, containing (say) a string, a boolean, and an integer. However, ROS 2 parameters do not support heterogenous lists, so any YAML list that has multiple types will be interpreted as a string. Assuming that


key: chroma:document
string_value:
multiple types will be interpreted as a string. Assuming that the parametermy_int_arrayon nodemy_nodeis of type integer array, the following will not work:ros param set /my_node my_int_array '[foo,off,1]'The following string typed parameter would work:ros param set /my_node my_string '[foo,off,1]'ros2paramdeleteThis command will remove a parameter from a particular node. However, note that this can only remove dynamic parameters (not declared parameters). Seethe concept documentfor more information.ros2 param delete /my_node my_stringros2paramdescribeThis command will provide a textual description of a particular parameter on a particular node:ros2 param describe /my_node use_sim_timeros2paramdumpThis command will print out all of the parameters on a particular node in a YAML file format. The output of this command can then be used to re-run the node with the same parameters later:ros2 param dump /my_noderos2paramloadThis command will load the values of the parameters from a YAML file into a particular


key: chroma:document
string_value:
the values of the parameters from a YAML file into a particular node. That is, this command can reload values at runtime that were dumped out byros2paramdump:ros2 param load /my_node my_node.yaml


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 param list /my_node

Language: unknown

ros2 param list

Language: unknown ros2 param get /my_node use_sim_time

Language: unknown ros2 param set /my_node use_sim_time false

Language: unknown ros2 param set /my_node my_string off

Language: unknown ros param set /my_node my_string '!!str off'

Language: unknown ros param set /my_node my_int_array '[foo,off,1]'

Language: unknown ros param set /my_node my_string '[foo,off,1]'

Language: unknown ros2 param delete /my_node my_string

Language: unknown ros2 param describe /my_node use_sim_time

Language: unknown

ros2 param dump /my_node

Language: unknown ros2 param load /my_node my_node.yaml


key: chroma:document
string_value:
Title: Building a custom deb package URL: https://docs.ros.org/en/jazzy/How-To-Guides/Building-a-Custom-Deb-Package.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Building a custom deb packageMany Ubuntu users install ROS 2 on their system by installingdeb packages. This guide gives a short set of instructions to build local, custom deb packages.Table of ContentsPrerequisitesInstall dependenciesInitialize rosdepBuild the deb from the packagePrerequisitesTo successfully build a custom package, all of the dependencies of the package to be built must be available locally or in rosdep. Additionally, all of the dependencies of the package should be properly declared in thepackage.xmlfile of the package.Install dependenciesRun the following command to install utilities needed for the build:$sudoaptinstallpython3-bloompython3-rosdepfakerootdebhelperdh-pythonInitialize rosdepInitialize the rosdep database by calling:$sudorosdepinit $rosdepupdateNote that therosdepinitcommand may fail if it has already been initialized in the past; this can safely be ignored.Build the deb from the packageRun the following commands to build the deb:$cd/path/to/pkg_source# this should be


key: chroma:document
string_value:
to build the deb:$cd/path/to/pkg_source# this should be the directory that contains the package.xml$bloom-generaterosdebian $fakerootdebian/rulesbinaryAssuming that all required dependencies are available and that compilation succeeds, the new package will be available in the parent directory of this directory.


key: chroma:document
string_value:
Code Examples:

Language: unknown

$sudoaptinstallpython3

bloompython3

rosdepfakerootdebhelperdh

python

Language: unknown

$sudorosdepinit

$rosdepupdate

Language: unknown $cd/path/to/pkg_source# this should be the directory that contains the package.xml$bloom-generaterosdebian $fakerootdebian/rulesbinary


key: chroma:document
string_value:
Title: Managing Dependencies with rosdep URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Rosdep.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Managing Dependencies with rosdepTable of ContentsWhat is rosdep?A little about package.xml files<depend><build_depend><build_export_depend><exec_depend><test_depend>How does rosdep work?How do I know what keys to put in my package.xml?What if my library isn’t in rosdistro?How do I use the rosdep tool?rosdep installationrosdep operationGoal:Manage external dependencies usingrosdep.Tutorial level:IntermediateTime:5 minutesThis tutorial will explain how to manage external dependencies usingrosdep.WarningCurrently rosdep only works on Linux and macOS; Windows is not supported. There are long-term plans to add support for Windows tohttps://github.com/ros-infrastructure/rosdep.What is rosdep?rosdepis a dependency management utility that can work with packages and external libraries. It is a command-line utility for identifying and installing dependencies to build or install a package.rosdepisnota package manager in its own right; it is a meta-package manager that uses its own knowledge of the system and the


key: chroma:document
string_value:
manager that uses its own knowledge of the system and the dependencies to find the appropriate package to install on a particular platform. The actual installation is done using the system package manager (e.g.apton Debian/Ubuntu,dnfon Fedora/RHEL, etc).It is most often invoked before building a workspace, where it is used to install the dependencies of the packages within that workspace.It has the ability to work over a single package or over a directory of packages (e.g. workspace).NoteWhile the name suggests it is for ROS,rosdepis semi-agnostic to ROS. You can utilize this powerful tool in non-ROS software projects by installing it as a standalone Python package. Successfully runningrosdeprelies onrosdepkeysto be available, which can be downloaded from a public git repository with a few simple commands.A little about package.xml filesThepackage.xmlis the file in your software whererosdepfinds the set of dependencies. It is important that the list of dependencies in thepackage.xmlis complete and correct,


key: chroma:document
string_value:
list of dependencies in thepackage.xmlis complete and correct, which allows all of the tooling to determine the packages dependencies. Missing or incorrect dependencies can lead to users not being able to use your package, to packages in a workspace being built out-of-order, and to packages not being able to be released.The dependencies in thepackage.xmlfile are generally referred to as “rosdep keys”. These dependencies are manually populated in thepackage.xmlfile by the package’s creators and should be an exhaustive list of any non-builtin libraries and packages it requires.These are represented in the following tags (seeREP-149for the full specification):<depend>These are dependencies that should be provided at both build time and run time for your package. For C++ packages, if in doubt, use this tag. Pure Python packages generally don’t have a build phase, so should never use this and should use<exec_depend>instead.<build_depend>If you only use a particular dependency for building your package, and not


key: chroma:document
string_value:
use a particular dependency for building your package, and not at execution time, you can use the<build_depend>tag.With this type of dependency, an installed binary of your package does not require that particular package to be installed.However, that can create a problem if your package exports a header that includes a header from this dependency. In that case you also need a<build_export_depend>.<build_export_depend>If you export a header that includes a header from a dependency, it will be needed by other packages that<build_depend>on yours. This mainly applies to headers and CMake configuration files. Library packages referenced by libraries you export should normally specify<depend>, because they are also needed at execution time.<exec_depend>This tag declares dependencies for shared libraries, executables, Python modules, launch scripts and other files required when running your package.<test_depend>This tag declares dependencies needed only by tests. Dependencies here shouldnotbe duplicated with


key: chroma:document
string_value:
only by tests. Dependencies here shouldnotbe duplicated with keys specified by<build_depend>,<exec_depend>, or<depend>.How does rosdep work?rosdepwill check forpackage.xmlfiles in its path or for a specific package and find the rosdep keys stored within. These keys are then cross-referenced against a central index to find the appropriate ROS package or software library in various package managers. Finally, once the packages are found, they are installed and ready to go!rosdepworks by retrieving the central index on to your local machine so that it doesn’t have to access the network every time it runs (on Debian/Ubuntu the configuration for it is stored in/etc/ros/rosdep/sources.list.d/20-default.list).The central index is known asrosdistro, whichmay be found online. We’ll explore that more in the next section.How do I know what keys to put in my package.xml?Great question, I’m glad you asked!If the package you want to depend in your package is ROS-based, AND has been released into the ROS ecosystem[1],


key: chroma:document
string_value:
is ROS-based, AND has been released into the ROS ecosystem[1], e.g.nav2_bt_navigator, you may simply use the name of the package. You can find a list of all released ROS packages inhttps://github.com/ros/rosdistroat<distro>/distribution.yaml(e.g.humble/distribution.yaml) for your given ROS distribution.If you want to depend on a non-ROS package, something often called “system dependencies”, you will need to find the keys for a particular library. In general, there are two files of interest:rosdep/base.yamlcontains theaptsystem dependenciesrosdep/python.yamlcontains the Python dependenciesTo find a key, search for your library in these files and find the name. This is the key to put in apackage.xmlfile.For example, imagine a package had a dependency ondoxygenbecause it is a great piece of software that cares about quality documentation (hint hint). We would searchrosdep/base.yamlfordoxygenand come


key: chroma:document
string_value:
(hint hint). We would searchrosdep/base.yamlfordoxygenand come across:doxygen:arch:[doxygen]debian:[doxygen]fedora:[doxygen]freebsd:[doxygen]gentoo:[app-doc/doxygen]macports:[doxygen]nixos:[doxygen]openembedded:[doxygen@meta-oe]opensuse:[doxygen]rhel:[doxygen]ubuntu:[doxygen]That means our rosdep key isdoxygen, which would resolve to those various names in different operating system’s package managers for installation.What if my library isn’t in rosdistro?If your library isn’t inrosdistro, you can experience the greatness that is open-source software development: you can add it yourself! Pull requests for rosdistro are typically merged well within a week.Detailed instructions may be found herefor how to contribute new rosdep keys. If for some reason these may not be contributed openly, it is possible to fork rosdistro and maintain a alternate index for use.How do I use the rosdep tool?rosdep installationIf you are usingrosdepwith ROS, it is conveniently packaged along with the ROS distribution. This is


key: chroma:document
string_value:
conveniently packaged along with the ROS distribution. This is the recommended way to getrosdep. You can install it with:apt-getinstallpython3-rosdepNoteOn Debian and Ubuntu, there is another, similarly named package calledpython3-rosdep2. If that package is installed, make sure to remove it before installingpython3-rosdep.If you are usingrosdepoutside of ROS, the system package may not be available. In that case, you can install it directly fromhttps://pypi.org:pipinstallrosdeprosdep operationNow that we have some understanding ofrosdep,package.xml, androsdistro, we’re ready to use the utility itself! Firstly, if this is the first time usingrosdep, it must be initialized via:sudorosdepinit rosdepupdateThis will initialize rosdep andupdatewill update the locally cached rosdistro index. It is a good idea toupdaterosdep on occasion to get the latest index.Finally, we can runrosdepinstallto install dependencies. Typically, this is run over a workspace with many packages in a single call to install all


key: chroma:document
string_value:
a workspace with many packages in a single call to install all dependencies. A call for that would appear as the following, if in the root of the workspace with directorysrccontaining source code.rosdepinstall--from-pathssrc-y--ignore-srcBreaking that down:--from-pathssrcspecifies the path to check forpackage.xmlfiles to resolve keys for-ymeans to default yes to all prompts from the package manager to install without prompts--ignore-srcmeans to ignore installing dependencies, even if a rosdep key exists, if the package itself is also in the workspace.There are additional arguments and options available. Userosdep-hto see them, or look at the more complete documentation for rosdep athttp://docs.ros.org/en/independent/api/rosdep/html/.[1]“released into the ROS ecosystem” means the package is listed in one or more of the<distro>/distribution.yamldirectories in therosdistro database.


key: chroma:document
string_value:
Code Examples:

Language: unknown

doxygen:arch:[doxygen]debian:[doxygen]fedora:[doxygen]freebsd:[doxygen]gentoo:[app

doc/doxygen]macports:[doxygen]nixos:[doxygen]openembedded:[doxygen@meta

oe]opensuse:[doxygen]rhel:[doxygen]ubuntu:[doxygen]

Language: unknown

apt

getinstallpython3

rosdep

Language: unknown

pipinstallrosdep

Language: unknown

sudorosdepinit

rosdepupdate

Language: unknown

rosdepinstall-

from

pathssrc

y-

ignore

src


key: chroma:document
string_value:
Title: Managing nodes with managed lifecycles URL: https://docs.ros.org/en/jazzy/Tutorials/Demos/Managed-Nodes.html Section: Installation --------------------------------------------------------------------------------

Managing nodes with managed lifecyclesThis page lives now directly side-by-side with thecode. For more information about thelifecyclepackage, refer torosindex.


key: chroma:document
string_value:
Title: ROS 2 Documentation

URL: https://docs.ros.org/en/jazzy/index.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
ROS 2 DocumentationThe Robot Operating System (ROS) is a set of software libraries and tools for building robot applications.From drivers and state-of-the-art algorithms to powerful developer tools, ROS has the open source tools you need for your next robotics project.Since ROS was started in 2007, a lot has changed in the robotics and ROS community. The goal of the ROS 2 project is to adapt to these changes, leveraging what is great about ROS 1 and improving what isn’t.Are you looking for documentation for a particular ROS package like MoveIt,  image_proc, or octomap?Please seeROS Indexor check outthis index of per-package documentation.This site contains the documentation for ROS 2. If you are looking for ROS 1 documentation, check out theROS wiki.If you use ROS 2 in your work, please seeCitationsto cite ROS 2.Getting startedInstallationInstructions to set up ROS 2 for the first timeTutorialsThe best place to start for new users!Hands-on sample projects that help you build a progression of necessary


key: chroma:document
string_value:
sample projects that help you build a progression of necessary skillsHow-to GuidesQuick answers to your “How do I…?” questions without working through theTutorialsConceptsHigh-level explanations of core ROS 2 concepts covered in theTutorialsContactAnswers to your questions or a forum to start a discussionThe ROS 2 projectIf you’re interested in the advancement of the ROS 2 project:ContributingBest practices and methodology for contributing to ROS 2, as well as instructions for migrating existing ROS 1 content to ROS 2DistributionsPast, present and future ROS 2 distributionsFeatures StatusFeatures in the current releaseFeature IdeasIdeas for nice-to-have features that are not under active developmentRoadmapPlanned work for ROS 2 developmentROSCon TalksPresentations by the community on ROS 2Project GovernanceInformation about the ROS Technical Steering Committee, Working Groups, and upcoming eventsMarketingDownloadable marketing materialsInformation about the ROS trademarkROS community resourcesIf you need


key: chroma:document
string_value:
about the ROS trademarkROS community resourcesIf you need help, have an idea, or would like to contribute to the project, please visit our ROS community resources.Official ROS Discord Channel for discussion and support(ROS 1, ROS 2)Robotics Stack Exchange - community Q&A website(ROS 1, ROS 2)SeeContact Pagefor more informationROS Discourse(ROS 1, ROS 2)Forum for general discussions and announcements for the ROS communitySee theContact Pagefor more informationROS Index(ROS 1, ROS 2)Indexed list of all packages (i.e.Python Package Index (PyPI)for ROS packages)See which ROS distributions a package supportsLink to a package’s repository, API documentation, or websiteInspect a package’s license, build type, maintainers, status, and dependenciesGet more info for a package onRobotics Stack ExchangeROS resource status page(ROS 1, ROS 2)Check the current status of ROS resources like Discourse or the ROS build farm.General ROS project resourcesROS Enhancement Proposals (REPs)(ROS 1, ROS 2)Proposals for new designs


key: chroma:document
string_value:
Proposals (REPs)(ROS 1, ROS 2)Proposals for new designs and conventionsROS Robots(ROS 1, ROS 2)Showcases robots projects from the communityInstructions on how to contribute a robotROS Wiki(ROS 1)ROS 1 documentation and user modifiable contentActive until at least the last ROS 1 distribution is EOLROS.org(ROS 1, ROS 2)ROS 1 and ROS 2 product landing page, with high-level description of ROS and links to other ROS sitesEventsOfficial ROS Vimeo Channel(ROS 1, ROS 2)Videos of ROSCon Talks, community and working group meetings, and project demos.ROSCon website(ROS 1, ROS 2)ROSCon is our annual ROS developer conference.This page also lists regional ROS events like ROSConJP and ROSConFr.Open Source Robotics Foundation official events calendarThis calendar is for official OSRF Events and working group meetings.Submit your events here.Open Source Robotics Foundation community calendarThis calendar is for unofficial ROS community events.Submit your events here.MiscellaneousPurchase official ROS swagROS on social


key: chroma:document
string_value:
here.MiscellaneousPurchase official ROS swagROS on social media@OpenRoboticsOrgand@ROSOrgon TwitterOpen Robotics on LinkedInVisit theOpen Source Robotics Foundation websiteTax deductible charitable donations to the Open Source Robotics Foundation can be sent viaDonorBox.DeprecatedROS 2 DesignEarly design decisions behind ROS 2 developmentNew design proposals should be submitted viaROS Enhancement Proposals (REPs)


key: chroma:document
string_value:
Title: Using Python Packages with ROS 2 URL: https://docs.ros.org/en/jazzy/How-To-Guides/Using-Python-Packages.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Using Python Packages with ROS 2Goal:Explain how to interoperate with other Python packages from the ROS 2 ecosystem.ContentsInstalling viarosdepInstalling via a package managerInstalling via a virtual environmentNoteA cautionary note, if you intended to use pre-packaged binaries (eitherdebfiles, or the binary archive distributions), the Python interpreter must match what was used to build the original binaries. If you intend to use something likevirtualenvorpipenv, make sure to use the system interpreter. If you use something likeconda, it is very likely that the interpreter will not match the system interpreter and will be incompatible with ROS 2 binaries.Installing viarosdepThe fastest way to include third-party python packages is to use their corresponding rosdep keys, if available.rosdepkeys can be checked via:https://github.com/ros/rosdistro/blob/master/rosdep/base.yamlhttps://github.com/ros/rosdistro/blob/master/rosdep/python.yamlTheserosdepkeys can be added to yourpackage.xmlfile, which indicates


key: chroma:document
string_value:
can be added to yourpackage.xmlfile, which indicates to the build system that your package (and dependent packages) depend on those keys. In a new workspace, you can also quickly install all rosdep keys with:rosdep install -yr ./path/to/your/workspaceIf there aren’t currentlyrosdepkeys for the package that you are interested in, it is possible to add them by following therosdep key contribution guide.To learn more about therosdeptool and how it works, consult therosdep documentation.Installing via a package managerIf you don’t want to make a rosdep key, but the package is available in your system package manager (egapt), you can install and use the package that way:sudo apt install python3-serialIf the package is available onThe Python Package Index (PyPI)and you want to install globally on your system:python3-mpipinstall-UpyserialIf the package is available on PyPI and you want to install locally to your user:python3 -m pip install -U --user pyserialInstalling via a virtual environmentFirst, create a


key: chroma:document
string_value:
pyserialInstalling via a virtual environmentFirst, create a Colcon workspace:mkdir -p ~/colcon_venv/srccd ~/colcon_venv/Then setup your virtual environment:#Makeavirtualenvandactivateitvirtualenv -p python3 ./venvsource ./venv/bin/activate#Makesurethatcolcondoesn’ttrytobuildthevenvtouch ./venv/COLCON_IGNORENext, install the Python packages that you want in your virtual environment:python3 -m pip install gtsam pyserial… etcNow you can build your workspace and run your python node that depends on packages installed in your virtual environment.#SourceJazzyandbuildsource /opt/ros/jazzy/setup.bashcolcon buildNoteIf you want to release your package using Bloom, you should add the packages you require torosdep, see therosdep key contribution guide.


key: chroma:document
string_value:
Code Examples:

Language: unknown

rosdep install

yr ./path/to/your/workspace

Language: unknown

sudo apt install python3

serial

Language: unknown

python3

mpipinstall

Upyserial

Language: unknown

python3

m pip install

U -

user pyserial

Language: unknown

mkdir

p ~/colcon_venv/srccd ~/colcon_venv/

Language: unknown #Makeavirtualenvandactivateitvirtualenv -p python3 ./venvsource ./venv/bin/activate#Makesurethatcolcondoesn’ttrytobuildthevenvtouch ./venv/COLCON_IGNORE

Language: unknown python3 -m pip install gtsam pyserial… etc

Language: unknown

#SourceJazzyandbuildsource /opt/ros/jazzy/setup.bashcolcon build


key: source
string_value:
/Users/ad12/ros2-rag/exported_docs/ros2/Deploying_on_IBM_Cloud_Kubernetes_[community-contributed].txt


key: chroma:document
string_value:
Title: Deploying on IBM Cloud Kubernetes [community-contributed] URL: https://docs.ros.org/en/jazzy/Tutorials/Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Deploying on IBM Cloud Kubernetes [community-contributed]Table of ContentsAboutROS 2 on IBM CloudStep 1: Setting up your systema) Docker files?b) ROS 2 ImageStep 2: Running the image on IBM CloudStep 3: Using Custom ROS 2 PackagesExtra: Deleting Docker ImagesStep 4: Kubernetesa) Creating the Clusterb) Deploying your Docker ImageFinally!Step 5: Using CLI for your Docker ImageFinal RemarksAboutThis article describes how to get ROS 2 running on IBM Cloud using Docker files. It first gives a brief overview of docker images and how they work locally and then explores IBM Cloud and how the user can deploy their containers on it. Afterwards, a short description of how the user can use their own custom packages for ROS 2 from github on IBM Cloud is provided. A walkthrough of how to create a cluster and utilize Kubernetes on IBM Cloud is provided and finally the Docker image is deployed on the cluster. Originally publishedhereandhere.ROS 2 on IBM CloudIn this tutorial, we show how you can easily integrate and run


key: chroma:document
string_value:
this tutorial, we show how you can easily integrate and run ROS 2 on IBM Cloud with your custom packages.ROS 2 is the new generation of ROS which gives more control over multi-robot formations. With the advancements of cloud computing, cloud robotics are becoming more important in today’s age. In this tutorial, we will go through a short introduction on running ROS 2 on IBM Cloud. By the end of the tutorial, you will be able to create your own packages in ROS 2 and deploy them to the cloud using docker files.The following instructions assume you’re using Linux and have been tested with Ubuntu 18.04 (Bionic Beaver).Step 1: Setting up your systemBefore we go into how the exact process works, lets first make sure all the required software is properly installed. We’ll point you towards the appropriate sources to set up your system and only highlight the details that pertain to our use-case.a) Docker files?Docker files are a form of containers that can run separate from your system, this way, you can set-up


key: chroma:document
string_value:
can run separate from your system, this way, you can set-up potentially hundreds of different projects without affecting one another. You can even set-up different versions of Linux on one machine, without the need for virtual machine. Docker files have an advantage of saving space and only utilizing your system resources when running. In addition, dockers are versatile and transferable. They contain all the required pre-requisites to run separately, meaning that you can easily use a docker file for a specific system or service without any cubersome steps!Excited yet? Let’s start off by installing docker to your system by following the followinglink. From the tutorial, you should have done some sanity checks to make sure docker is properly set-up. Just in case, however, let’s run the following command once again that uses the hello-world docker image:$sudodockerrunhello-worldYou should obtain the following output:HellofromDocker! Thismessageshowsthatyourinstallationappearstobeworkingcorrectly.


key: chroma:document
string_value:
Togeneratethismessage,Dockertookthefollowingsteps:1.TheDockerclientcontactedtheDockerdaemon.2.TheDockerdaemonpulledthe"hello

world"imagefromtheDockerHub.(amd64)3.TheDockerdaemoncreatedanewcontainerfromthatimagewhichrunstheexecutablethatproducestheoutputyouarecurrentlyreading.4.TheDockerdaemonstreamedthatoutputtotheDockerclient,whichsentittoyourterminal.

Totrysomethingmoreambitious,youcanrunanUbuntucontainerwith:$dockerrun

itubuntubash

Shareimages,automateworkflows,andmorewithafreeDockerID:https://hub.docker.com/


key: chroma:document
string_value:
Formoreexamplesandideas,visit:https://docs.docker.com/get-started/b) ROS 2 ImageROSannouncedimage containers for several ROS distributions in January 2019. More detailed instructions on the use of ROS 2 docker images can be foundhere.Let’s skip through that and get to real-deal right away; creating a local ROS 2 docker. We’ll create our own Dockerfile (instead of using a ready Image) since we’ll need this method for deployment on IBM Cloud. First, we create a new directory which will hold our Dockerfile and any other files we need later on and navigate to it. Using your favorite $EDITOR of choice, open a new file namedDockerfile(make sure the file naming is correct):$mkdir~/ros2_docker

$cd~/ros2_docker

$$EDITORDockerfileInsert the following in theDockerfile, and save it (also foundhere):FROMros:foxy# install ros packageRUNapt-getupdate&&apt-getinstall-y\ros-${ROS_DISTRO}-demo-nodes-cpp\ros-${ROS_DISTRO}-demo-nodes-py&&\rm-rf/var/lib/apt/lists/*&&mkdir/ros2_home


key: chroma:document
string_value:
WORKDIR/ros2_home# launch ros packageCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]FROM: creates a layer from the ros:foxy Docker imageRUN: builds your container by installing vim into it and creating a directory called /ros2_homeWORKDIR: informs the container where the working directory should be for itOf course, you are free to change the ROS distribution (foxyis used here) or change the directory name. The above docker file sets up ROS-foxy and installs the demo nodes for C++ and Python. Then it launches a file which runs a talker and a listener node. We will see it in action in just a few, but they act very similar to the publisher-subscriber example found in theROS wikiNow, we are ready to build the docker image to run ROS 2 in it (yes, it is THAT easy!).Note: if you have errors due to insufficient privileges orpermission denied, try running the command withsudoprivileges:$dockerbuild.# You will see a bunch of lines that execute the docker file instructions followed


key: chroma:document
string_value:
of lines that execute the docker file instructions followed by:Successfullybuilt0dc6ce7cb4870dc6ce7cb487will most probably be different for you, so keep note of it and copy it somewhere for reference. You can always go back and check the docker images you have on your system using:$sudodockerps-asNow, run the docker file using:$dockerrun-it0dc6ce7cb487[INFO][launch]:Alllogfilescanbefoundbelow/root/.ros/log/2020-10-28-02-41-45-177546-0b5d9ed123be-1[INFO][launch]:DefaultloggingverbosityissettoINFO[INFO][talker-1]:processstartedwithpid[28][INFO][listener-2]:processstartedwithpid[30][talker-1][INFO][1603852907.249886590][talker]:Publishing:'Hello World: 1'[listener-2][INFO][1603852907.250964490][listener]:Iheard:[HelloWorld:1][talker-1][INFO][1603852908.249786312][talker]:Publishing:'Hello World: 2'[listener-2][INFO][1603852908.250453386][listener]:Iheard:[HelloWorld:2][talker-1][INFO][1603852909.249882257][talker]:Publishing:'Hello World:


key: chroma:document
string_value:
World: 3'[listener-2][INFO][1603852909.250536089][listener]:Iheard:[HelloWorld:3][talker-1][INFO][1603852910.249845718][talker]:Publishing:'Hello World: 4'[listener-2][INFO][1603852910.250509355][listener]:Iheard:[HelloWorld:4][talker-1][INFO][1603852911.249506058][talker]:Publishing:'Hello World: 5'[listener-2][INFO][1603852911.250152324][listener]:Iheard:[HelloWorld:5][talker-1][INFO][1603852912.249556670][talker]:Publishing:'Hello World: 6'[listener-2][INFO][1603852912.250212678][listener]:Iheard:[HelloWorld:6]If it works correctly, you should see something similar to what is shown above. As can be seen, there are two ROS nodes (a publisher and a subscriber) running and their output is provided to us through ROS INFO.Step 2: Running the image on IBM CloudThe following steps assume you have an IBM cloud account and have ibmcloud CLI installed. If not, please check thislinkout to get that done first.We also need to make sure that the CLI plug-in for the IBM Cloud Container Registry is installed by running


key: chroma:document
string_value:
for the IBM Cloud Container Registry is installed by running the command$ibmcloudplugininstallcontainer-registryAfterwards, login to your ibmcloud account through the terminal:$ibmcloudlogin--ssoFrom here, let’s create a container registry name-space. Make sure you use a unique name that is also descriptive as to what it is. Here, I usedros2nasr.$ibmcloudcrnamespace-addros2nasrIBM cloud has a lot of shortcuts that would help us get our container onto the cloud right away. The command below builds the container and tags it with the nameros2foxyand the version of1. Make sure you use the correct registry name you created and you are free to change the container name as you wish. The.at the end indicates that theDockerfileis in the current directory (and it is important), if not, change it to point to the directory containing the Dockerfile.$ibmcloudcrbuild--tagregistry.bluemix.net/ros2nasr/ros2foxy:1.You can now make sure that the container has been pushed to the registry you created by running the following


key: chroma:document
string_value:
pushed to the registry you created by running the following command$ibmcloudcrimage-list Listingimages...


key: chroma:document
string_value:
REPOSITORYTAGDIGESTNAMESPACECREATEDSIZESECURITYSTATUS

us.icr.io/ros2nasr/ros2foxy1031be29301e6ros2nasr36secondsago120MBNoIssues

OKNext, it is important to log-in to your registry to run the docker image. Again, if you face apermission deniederror, perform the command with sudo privileges. Afterwards, run your docker file as shown below.$ibmcloudcrlogin Logginginto'registry.ng.bluemix.net'... Loggedinto'registry.ng.bluemix.net'. Logginginto'us.icr.io'... Loggedinto'us.icr.io'.

OK


key: chroma:document
string_value:
$dockerrun-v-itregistry.ng.bluemix.net/ros2nasr/ros2foxy:1Whereros2nasris the name of the registry you created andros2foxy:1is the tag of the docker container and the version as explained previously.You should now see your docker file running and providing similar output to that you saw when you ran it locally on your machine.Step 3: Using Custom ROS 2 PackagesSo now we have the full pipeline working, from creating the Dockerfile, all the way to deploying it and seeing it work on IBM Cloud. But, what if we want to use a custom set of packages we (or someone else) created?Well that all has to do with how you set-up your Dockerfile. Lets use the example provided by ROS 2here. Create a new directory with a new Dockerfile (or overwrite the existing one) and add the following in it (or download the filehere)ARGFROM_IMAGE=ros:foxy ARGOVERLAY_WS=/opt/ros/overlay_ws# multi-stage for cachingFROM$FROM_IMAGEAScacher# clone overlay sourceARGOVERLAY_WS WORKDIR$OVERLAY_WS/src RUNecho"\repositories: \n\ros2/demos:


key: chroma:document
string_value:
WORKDIR$OVERLAY_WS/src RUNecho"\repositories: \n\ros2/demos: \n\type: git \n\url: https://github.com/ros2/demos.git \n\version:${ROS_DISTRO}\n\">../overlay.repos RUNvcsimport./<../overlay.repos# copy manifests for cachingWORKDIR/opt RUNmkdir-p/tmp/opt&&\find./-name"package.xml"|\xargscp--parents-t/tmp/opt&&\find./-name"COLCON_IGNORE"|\xargscp--parents-t/tmp/opt||true# multi-stage for buildingFROM$FROM_IMAGEASbuilder# install overlay dependenciesARGOVERLAY_WS WORKDIR$OVERLAY_WSCOPY--from=cacher/tmp/$OVERLAY_WS/src./src RUN./opt/ros/$ROS_DISTRO/setup.sh&&\apt-getupdate&&rosdepinstall-y\--from-paths\src/ros2/demos/demo_nodes_cpp\src/ros2/demos/demo_nodes_py\--ignore-src\&&rm-rf/var/lib/apt/lists/*# build overlay sourceCOPY--from=cacher$OVERLAY_WS/src./src ARGOVERLAY_MIXINS="release"RUN./opt/ros/$ROS_DISTRO/setup.sh&&\colconbuild\--packages-select\demo_nodes_cpp\demo_nodes_py\--mixin$OVERLAY_MIXINS# source entrypoint setupENVOVERLAY_WS$OVERLAY_WSRUNsed--in-place--expression\'$isource


key: chroma:document
string_value:
"$OVERLAY_WS/install/setup.bash"'\/ros_entrypoint.sh# run launch fileCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]Going through the lines shown, we can see how we can add custom packages from github in 4 steps:Create an overlay with custom packages cloned from Github:ARGOVERLAY_WS WORKDIR$OVERLAY_WS/src RUNecho"\repositories: \n\ros2/demos: \n\type: git \n\url: https://github.com/ros2/demos.git \n\version:${ROS_DISTRO}\n\">../overlay.repos RUNvcsimport./<../overlay.reposInstall package dependencies using rosdep# install overlay dependenciesARGOVERLAY_WS WORKDIR$OVERLAY_WSCOPY--from=cacher/tmp/$OVERLAY_WS/src./src RUN./opt/ros/$ROS_DISTRO/setup.sh&&\apt-getupdate&&rosdepinstall-y\--from-paths\src/ros2/demos/demo_nodes_cpp\src/ros2/demos/demo_nodes_py\--ignore-src\&&rm-rf/var/lib/apt/lists/*Build the packagesyou need# build overlay sourceCOPY--from=cacher$OVERLAY_WS/src./src


key: chroma:document
string_value:
need# build overlay sourceCOPY--from=cacher$OVERLAY_WS/src./src ARGOVERLAY_MIXINS="release"RUN./opt/ros/$ROS_DISTRO/setup.sh&&\colconbuild\--packages-select\demo_nodes_cpp\demo_nodes_py\--mixin$OVERLAY_MIXINSRunning the launch file# run launch fileCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]Likewise, we can change the packages used, install their dependencies, and then run them.Back to IBM CloudWith this Dockerfile, we can follow the same steps we did before to deploy it on IBM Cloud. Since we already have our registry created, and we’re logged in to IBM Cloud, we directly build our new Dockerfile. Notice how I kept the tag the same but changed the version, this way I can update the docker image created previously. (You are free to create a completely new one if you want)$ibmcloudcrbuild--tagregistry.bluemix.net/ros2nasr/ros2foxy:2.Then, make sure you are logged in to the registry and run the new docker image:$ibmcloudcrlogin Logginginto'registry.ng.bluemix.net'...


key: chroma:document
string_value:
image:$ibmcloudcrlogin Logginginto'registry.ng.bluemix.net'... Loggedinto'registry.ng.bluemix.net'. Logginginto'us.icr.io'... Loggedinto'us.icr.io'.


key: chroma:document
string_value:
$dockerrun-v-itregistry.ng.bluemix.net/ros2nasr/ros2foxy:2You should see, again, the same output. However, this time we did it through custom packages from github, which allows us to utilize our personally created packages for ROS 2 on IBM Cloud.Extra: Deleting Docker ImagesAs you may find yourself in need of deleting a specific docker image(s) from IBM Cloud, this is how you should go about it!List all the images you have and find all the ones that share theIMAGEname corresponding toregistry.ng.bluemix.net/ros2nasr/ros2foxy:2(in my case). Then delete them using theirNAMES$dockerrmyour_docker_NAMESDelete the docker image from IBM Cloud using itsIMAGEname$dockerrmiregistry.ng.bluemix.net/ros2nasr/ros2foxy:2Step 4: Kubernetesa) Creating the ClusterCreate a cluster using the Console. The instructions are foundhere. The settings used are detailed below. These are merely suggestions and can be changed if you need to. However, make sure you understand the implications of your choices:Plan:StandardOrchestration


key: chroma:document
string_value:
the implications of your choices:Plan:StandardOrchestration Service:Kubernetes v1.18.10Infrastructure:ClassicLocation:Resource group:DefaultGeography:North America(you are free to change this)Availability:Single zone(you are free to change this but make sure you understand the impact of your choices by checking the IBM Cloud documentation.)Worker Zone:Toronto 01(choose the location that is physically closest to you)Worker Pool:Virtual - shared, Ubuntu 18Memory: 16 GBWorker nodes per zone:1Master service endpoint:Both private & public endpointsResource details (Totally flexible):Cluster name:mycluster-tor01-rosibmTags:version:1After you create your cluster, you will be redirected to a page which details how you can set up the CLI tools and access your cluster. Please follow these instructions (or check the instructionshere)and wait for the progress bar to show that the worker nodes you created are ready by indicatingNormalnext to the cluster name. You can also reach this screen from the IBM Cloud Console


key: chroma:document
string_value:
name. You can also reach this screen from the IBM Cloud Console inside the Kubernetes.b) Deploying your Docker ImageFinally!Create a deployment configuration yaml file namedros2-deployment.yamlusing your favorite $EDITOR and insert the following in it:apiVersion:apps/v1 kind:Deployment metadata:name:<deployment> spec:replicas:<number_of_replicas>selector:matchLabels:app:<app_name>template:metadata:labels:app:<app_name>spec:containers:-name:<app_name>image:<region>.icr.io/<namespace>/<image>:<tag>You should replace the tags shown between“<” “>”as describedhere. The file in my case would look something like this:apiVersion:apps/v1 kind:Deployment metadata:name:ros2-deployment spec:replicas:1selector:matchLabels:app:ros2-ibmcloudtemplate:metadata:labels:app:ros2-ibmcloudspec:containers:-name:ros2-ibmcloudimage:us.icr.io/ros2nasr/ros2foxy:2Deploy the file using the following command$kubectlapply-fros2-deployment.yaml deployment.apps/ros2-deploymentcreatedNow your docker image is fully deployed on your


key: chroma:document
string_value:
your docker image is fully deployed on your cluster!Step 5: Using CLI for your Docker ImageNavigate to your cluster through the IBM Cloud console Kubernetes.Click onKubernetes dashboardon the top right corner of the page.You should now be able to see a full list of all the different parameters of your cluster as well as its CPU and Memory Usage.Navigate toPodsand click on your deployment.On the top right corner, click onExec into podNow you are inside your docker image! You can source your workspace (if needed) and run ROS 2! For example:root@ros2-deployment-xxxxxxxx:/opt/ros/overlay_ws#.install/setup.sh root@ros2-deployment-xxxxxxxx:/opt/ros/overlay_ws#ros2launchdemo_nodes_cpptalker_listener_launch.pyFinal RemarksAt this point, you are capable of creating your own docker image using ROS 2 packages on github. It is also possible, with little changes to utilize local ROS 2 packages as well. This could be the topic of another article. However, you are encouraged to check out the followingDockerfilewhich uses


key: chroma:document
string_value:
are encouraged to check out the followingDockerfilewhich uses a local copy of the demos repository. Similarly, you can use your own local package.


key: chroma:document
string_value:
Code Examples:

Language: unknown

$sudodockerrunhello

world

Language: unknown

HellofromDocker!

Thismessageshowsthatyourinstallationappearstobeworkingcorrectly.

Togeneratethismessage,Dockertookthefollowingsteps:1.TheDockerclientcontactedtheDockerdaemon.2.TheDockerdaemonpulledthe"hello

world"imagefromtheDockerHub.(amd64)3.TheDockerdaemoncreatedanewcontainerfromthatimagewhichrunstheexecutablethatproducestheoutputyouarecurrentlyreading.4.TheDockerdaemonstreamedthatoutputtotheDockerclient,whichsentittoyourterminal.

Totrysomethingmoreambitious,youcanrunanUbuntucontainerwith:$dockerrun

itubuntubash

Shareimages,automateworkflows,andmorewithafreeDockerID:https://hub.docker.com/

Formoreexamplesandideas,visit:https://docs.docker.com/get

started/

Language: unknown

$mkdir~/ros2_docker

$cd~/ros2_docker

$$EDITORDockerfile

Language: unknown

FROMros:foxy# install ros packageRUNapt

getupdate&&apt

getinstall

y\ros

${ROS_DISTRO}

demo

nodes

cpp\ros

${ROS_DISTRO}

demo

nodes

py&&\rm


key: chroma:document
string_value:
demo

nodes

cpp\ros

${ROS_DISTRO}

demo

nodes

py&&\rm

rf/var/lib/apt/lists/

&&mkdir/ros2_home

WORKDIR/ros2_home# launch ros packageCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]

Language: unknown $dockerbuild.# You will see a bunch of lines that execute the docker file instructions followed by:Successfullybuilt0dc6ce7cb487

Language: unknown

$sudodockerps

as

Language: unknown

$dockerrun

it0dc6ce7cb487[INFO][launch]:Alllogfilescanbefoundbelow/root/.ros/log/2020

10

28

02

41

45

177546

0b5d9ed123be

1[INFO][launch]:DefaultloggingverbosityissettoINFO[INFO][talker

1]:processstartedwithpid[28][INFO][listener

2]:processstartedwithpid[30][talker

1][INFO][1603852907.249886590][talker]:Publishing:'Hello World: 1'[listener

2][INFO][1603852907.250964490][listener]:Iheard:[HelloWorld:1][talker

1][INFO][1603852908.249786312][talker]:Publishing:'Hello World: 2'[listener

2][INFO][1603852908.250453386][listener]:Iheard:[HelloWorld:2][talker


key: chroma:document
string_value:
1][INFO][1603852909.249882257][talker]:Publishing:'Hello World: 3'[listener

2][INFO][1603852909.250536089][listener]:Iheard:[HelloWorld:3][talker

1][INFO][1603852910.249845718][talker]:Publishing:'Hello World: 4'[listener

2][INFO][1603852910.250509355][listener]:Iheard:[HelloWorld:4][talker

1][INFO][1603852911.249506058][talker]:Publishing:'Hello World: 5'[listener

2][INFO][1603852911.250152324][listener]:Iheard:[HelloWorld:5][talker

1][INFO][1603852912.249556670][talker]:Publishing:'Hello World: 6'[listener

2][INFO][1603852912.250212678][listener]:Iheard:[HelloWorld:6]

Language: unknown

$ibmcloudplugininstallcontainer

registry

Language: unknown

$ibmcloudlogin-

sso

Language: unknown

$ibmcloudcrnamespace

addros2nasr

Language: unknown

$ibmcloudcrbuild-

tagregistry.bluemix.net/ros2nasr/ros2foxy:1.

Language: unknown

$ibmcloudcrimage

list

Listingimages...

REPOSITORYTAGDIGESTNAMESPACECREATEDSIZESECURITYSTATUS

us.icr.io/ros2nasr/ros2foxy1031be29301e6ros2nasr36secondsago120MBNoIssues

OK


key: chroma:document
string_value:
OK

Language: unknown

$ibmcloudcrlogin

Logginginto'registry.ng.bluemix.net'...

Loggedinto'registry.ng.bluemix.net'.

Logginginto'us.icr.io'...

Loggedinto'us.icr.io'.

OK

$dockerrun

v

itregistry.ng.bluemix.net/ros2nasr/ros2foxy:1


key: chroma:document
string_value:
Language: unknown ARGFROM_IMAGE=ros:foxy ARGOVERLAY_WS=/opt/ros/overlay_ws# multi-stage for cachingFROM$FROM_IMAGEAScacher# clone overlay sourceARGOVERLAY_WS WORKDIR$OVERLAY_WS/src RUNecho"\repositories: \n\ros2/demos: \n\type: git \n\url: https://github.com/ros2/demos.git \n\version:${ROS_DISTRO}\n\">../overlay.repos RUNvcsimport./<../overlay.repos# copy manifests for cachingWORKDIR/opt RUNmkdir-p/tmp/opt&&\find./-name"package.xml"|\xargscp--parents-t/tmp/opt&&\find./-name"COLCON_IGNORE"|\xargscp--parents-t/tmp/opt||true# multi-stage for buildingFROM$FROM_IMAGEASbuilder# install overlay dependenciesARGOVERLAY_WS WORKDIR$OVERLAY_WSCOPY--from=cacher/tmp/$OVERLAY_WS/src./src RUN./opt/ros/$ROS_DISTRO/setup.sh&&\apt-getupdate&&rosdepinstall-y\--from-paths\src/ros2/demos/demo_nodes_cpp\src/ros2/demos/demo_nodes_py\--ignore-src\&&rm-rf/var/lib/apt/lists/*# build overlay sourceCOPY--from=cacher$OVERLAY_WS/src./src


key: chroma:document
string_value:
build overlay sourceCOPY--from=cacher$OVERLAY_WS/src./src ARGOVERLAY_MIXINS="release"RUN./opt/ros/$ROS_DISTRO/setup.sh&&\colconbuild\--packages-select\demo_nodes_cpp\demo_nodes_py\--mixin$OVERLAY_MIXINS# source entrypoint setupENVOVERLAY_WS$OVERLAY_WSRUNsed--in-place--expression\'$isource "$OVERLAY_WS/install/setup.bash"'\/ros_entrypoint.sh# run launch fileCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]


key: chroma:document
string_value:
Language: unknown ARGOVERLAY_WS WORKDIR$OVERLAY_WS/src RUNecho"\repositories: \n\ros2/demos: \n\type: git \n\url: https://github.com/ros2/demos.git \n\version:${ROS_DISTRO}\n\">../overlay.repos RUNvcsimport./<../overlay.repos

Language: unknown

# install overlay dependenciesARGOVERLAY_WS

WORKDIR$OVERLAY_WSCOPY-

from=cacher/tmp/$OVERLAY_WS/src./src

RUN./opt/ros/$ROS_DISTRO/setup.sh&&\apt

getupdate&&rosdepinstall

y\-

from

paths\src/ros2/demos/demo_nodes_cpp\src/ros2/demos/demo_nodes_py\-

ignore

src\&&rm

rf/var/lib/apt/lists/*

Language: unknown

# build overlay sourceCOPY-

from=cacher$OVERLAY_WS/src./src

ARGOVERLAY_MIXINS="release"RUN./opt/ros/$ROS_DISTRO/setup.sh&&\colconbuild\-

packages

select\demo_nodes_cpp\demo_nodes_py\-

mixin$OVERLAY_MIXINS

Language: unknown

# run launch fileCMD["ros2","launch","demo_nodes_cpp","talker_listener_launch.py"]

Language: unknown

$ibmcloudcrbuild-

tagregistry.bluemix.net/ros2nasr/ros2foxy:2.

Language: unknown

$ibmcloudcrlogin


key: chroma:document
string_value:
Language: unknown

$ibmcloudcrlogin

Logginginto'registry.ng.bluemix.net'...

Loggedinto'registry.ng.bluemix.net'.

Logginginto'us.icr.io'...

Loggedinto'us.icr.io'.

OK

$dockerrun

v

itregistry.ng.bluemix.net/ros2nasr/ros2foxy:2

Language: unknown

$dockerrmyour_docker_NAMES

Language: unknown

$dockerrmiregistry.ng.bluemix.net/ros2nasr/ros2foxy:2

Language: unknown

apiVersion:apps/v1

kind:Deployment

metadata:name:<deployment>

spec:replicas:<number_of_replicas>selector:matchLabels:app:<app_name>template:metadata:labels:app:<app_name>spec:containers:

name:<app_name>image:<region>.icr.io/<namespace>/<image>:<tag>

Language: unknown

apiVersion:apps/v1

kind:Deployment

metadata:name:ros2

deployment

spec:replicas:1selector:matchLabels:app:ros2

ibmcloudtemplate:metadata:labels:app:ros2

ibmcloudspec:containers:

name:ros2

ibmcloudimage:us.icr.io/ros2nasr/ros2foxy:2

Language: unknown

$kubectlapply

fros2

deployment.yaml

deployment.apps/ros2

deploymentcreated

Language: unknown

root@ros2


key: chroma:document
string_value:
deploymentcreated

Language: unknown

root@ros2

deployment

xxxxxxxx:/opt/ros/overlay_ws#.install/setup.sh

root@ros2

deployment

xxxxxxxx:/opt/ros/overlay_ws#ros2launchdemo_nodes_cpptalker_listener_launch.py


key: chroma:document
string_value:
Title: Migrating Interfaces

URL: https://docs.ros.org/en/jazzy/How

To

Guides/Migrating

from

ROS1/Migrating

Interfaces.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Migrating InterfacesTable of ContentsInterface definitionsBuilding interfacesMigrating interface package to ROS 2Messages, services, and actions are collectively calledinterfacesin ROS 2.Interface definitionsMessage files must end in.msgand must be located in the subfoldermsg. Service files must end in.srvand must be located in the subfoldersrv. Actions files must end in.actionand must be located in the subfolderaction.These files might need to be updated to comply with theROS Interface definition. Some primitive types have been removed and the typesdurationandtimewhich were builtin types in ROS 1 have been replaced with normal message definitions and must be used from thebuiltin_interfacespackage. Also some naming conventions are stricter than in ROS 1. There is additional information in theconceptual article.Building interfacesThe way in which interfaces are built in ROS 2 differs substantially from ROS 1. Interfaces can only be built from packages containing aCMakeLists.txt. If you are developing a


key: chroma:document
string_value:
packages containing aCMakeLists.txt. If you are developing a pure Python package, then the interfaces should be placed in a different package containing only the interfaces (which is best practice anyway). See thecustom interfaces tutorialfor more information.Migrating interface package to ROS 2In yourpackage.xml:Add<buildtool_depend>rosidl_default_generators</buildtool_depend>.Add<exec_depend>rosidl_default_runtime</exec_depend>.Add<member_of_group>rosidl_interface_packages</member_of_group>For each dependent message package, add<depend>message_package</depend>.In yourCMakeLists.txt:Enable C++17set(CMAKE_CXX_STANDARD17)Addfind_package(rosidl_default_generatorsREQUIRED)For each dependent message package, addfind_package(message_packageREQUIRED)and replace the CMake function call togenerate_messageswithrosidl_generate_interfaces.This will replaceadd_message_filesandadd_service_fileslisting of all the message and service files, which can be removed.


key: chroma:document
string_value:
Title: Webots

URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Simulators/Webots/Simulation

Webots.html

Section: Installation

--------------------------------------------------------------------------------

WebotsThis set of tutorials will teach you how to configure the Webots simulator with ROS 2.Installation (Ubuntu)Installation (Windows)Installation (macOS)Setting up a robot simulation (Basic)Setting up a robot simulation (Advanced)Setting up a Reset HandlerThe Ros2Supervisor Node


key: chroma:document
string_value:
Title: Crystal Clemmys (crystal)

URL: https://docs.ros.org/en/jazzy/Releases/Release

Crystal

Clemmys.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Crystal Clemmys (crystal)Table of ContentsSupported PlatformsNew features in this ROS 2 releaseChanges since the Bouncy releaseKnown IssuesCrystal Clemmysis the third release of ROS 2.Supported PlatformsCrystal Clemmys is primarily supported on the following platforms (seeREP 2000for full details):Tier 1 platforms:Ubuntu 18.04 (Bionic)Mac macOS 10.12 (Sierra)Windows 10Tier 2 platforms:Ubuntu 16.04 (Xenial)New features in this ROS 2 releaseActions in C / C++ (server/clientexamples)gazebo_ros_pkgsimage_transportnavigation2rosbag2rqtImprovement in memory managementIntrospection information about nodesLaunch system improvementsArgumentsNested launch filesConditionsPass params to NodesLaid the groundwork forfile-based logging and /rosout publishingTime and Duration API in PythonParameters work with Python nodesChanges since the Bouncy releaseChanges since theBouncy Bolsonrelease:geometry2 -tf2_ros::BufferAPI Changetf2_ros::Buffernow usesrclcpp::Time, with the constructor requiring ashared_ptrto


key: chroma:document
string_value:
usesrclcpp::Time, with the constructor requiring ashared_ptrto arclcpp::Clockinstance. Seehttps://github.com/ros2/geometry2/pull/67for details, with example usage:#include<tf2_ros/transform_listener.h>#include<rclcpp/rclcpp.hpp>...# Assuming you have a rclcpp::Node my_nodetf2_ros::Bufferbuffer(my_node.get_clock());tf2_ros::TransformListenertf_listener(buffer);Allrclcppandrcutilslogging macros require semicolons.Seehttps://github.com/ros2/rcutils/issues/113for details.rcutils_get_error_string_safe()andrcl_get_error_string_safe()have been replaced withrcutils_get_error_string().strandrcl_get_error_string().str.Seehttps://github.com/ros2/rcutils/pull/121for details.rmw -rmw_initAPI ChangeThere are two new structs, thercl_context_tand thercl_init_options_t, which are used withrmw_init. The init options struct is used to pass options down to the middleware and is an input tormw_init. The context is a handle which is an output ofrmw_initfunction is used to identify which init-shutdown cycle each entity is


key: chroma:document
string_value:
is used to identify which init-shutdown cycle each entity is associated with, where an “entity” is anything created like a node, guard condition, etc.This is listed here because maintainers of alternative rmw implementations will need to implement these new functions to have their rmw implementation work in Crystal.This is the function that had a signature change:rmw_initAdditionally, there are these new functions which need to be implemented by each rmw implementation:rmw_shutdownrmw_init_options_initrmw_init_options_copyrmw_init_options_finiHere’s an example of what minimally needs to be changed in an rmw implementation to adhere to this API change:rmw_fastrtps prrcl -rcl_initAPI ChangeLike thermwchange above, there’s two new structs inrclcalledrcl_context_tandrcl_init_options_t. The init options are passed intorcl_initas an input and the context is passed in as an output. The context is used to associate all other rcl entities to a specific init-shutdown cycle, effectively making init and shutdown no


key: chroma:document
string_value:
init-shutdown cycle, effectively making init and shutdown no longer global functions, or rather those functions no longer use an global state and instead encapsulate all state within the context type.Any maintainers of a client library implementation (that also usesrclunder the hood) will need to make changes to work with Crystal.These functions were removed:rcl_get_global_argumentsrcl_get_instance_idrcl_okThese functions had signature changes:rcl_initrcl_shutdownrcl_guard_condition_initrcl_guard_condition_init_from_rmwrcl_node_initrcl_timer_initThese are the new functions and types:rcl_context_trcl_get_zero_initialized_contextrcl_context_finircl_context_get_init_optionsrcl_context_get_instance_idrcl_context_is_validrcl_init_options_trcl_get_zero_initialized_init_optionsrcl_init_options_initrcl_init_options_copyrcl_init_options_finircl_init_options_get_rmw_init_optionsrcl_node_is_valid_except_contextrcl_publisher_get_contextrcl_publisher_is_valid_except_contextThese new and changed functions will impact how


key: chroma:document
string_value:
new and changed functions will impact how you handle init and shutdown in your client library. For examples, look at the followingrclcppandrclpyPR’s:rclcpprclpyHowever, you may just continue to offer a single, global init and shutdown in your client library, and just store a single global context object.Known IssuesA race condition in Fast-RTPS 1.7.0 may cause messages to drop under stress (Issue).Using the TRANSIENT_LOCAL QoS setting with rmw_fastrtps_cpp can crash applications with large messages (Issue).Cross-vendor communication between rmw_fastrtps_cpp and other implementations is not functioning on Windows (Issue).When using OpenSplice (version < 6.9.190227) on macOS and Windows you might experience naming conflicts when when referencing field types with names from other packages if the same name also exist in the current package (Issue). By updating to a newer OpenSplice version as well as at least the third patch release of Crystal the problem should be resolved. On Linux updating to the latest


key: chroma:document
string_value:
the problem should be resolved. On Linux updating to the latest Debian packages will include the newest OpenSplice version.


key: chroma:document
string_value:
Code Examples:

Language: unknown #include<tf2_ros/transform_listener.h>#include<rclcpp/rclcpp.hpp>...# Assuming you have a rclcpp::Node my_nodetf2_ros::Bufferbuffer(my_node.get_clock());tf2_ros::TransformListenertf_listener(buffer);


key: chroma:document
string_value:
Title: Beta 2 (r2b2)

URL: https://docs.ros.org/en/jazzy/Releases/Beta2

Overview.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Beta 2 (r2b2)Table of ContentsSupported PlatformsFeaturesImprovements since Beta 1 releaseNew demo applicationSelected features from previous Alpha/Beta releasesKnown issuesSupported PlatformsWe support ROS 2 Beta 2 on three platforms: Ubuntu 16.04 (Xenial), macOS 10.12 (Sierra), and Windows 10. We provide both binary packages and instructions for how to compile from source for all 3 platforms (seeinstall instructionsas well asdocumentation).FeaturesImprovements since Beta 1 releaseDDS_Security support (aka SROS2, seesros2)Debian packages for Ubuntu XenialTypesupport has been redesigned so that you only build a single executable and can choose one of the available RMW implementations by setting an environment variable (seedocumentation).Namespace support for nodes and topics (seedesign article, see known issues below).A set of command-line tools using the extensibleros2command (seeconceptual article).A set of macros for logging messages in C / C++ (see API docs ofrcutils).New demo applicationTurtlebot 2


key: chroma:document
string_value:
/ C++ (see API docs ofrcutils).New demo applicationTurtlebot 2 demosusing the following repositories that have been (partially) converted to ROS 2 (Linux only):ros_astra_cameradepthimage_to_laserscanpcl_conversionscartographercartographer_rosceres-solvernavigationteleop_twist_keyboardjoystick_driversteleop_twist_joyDummy_robot demo:robot_modelrobot_state_publisherSelected features from previous Alpha/Beta releasesFor the complete list, seeearlier release notes.C++ and Python implementations of ROS 2 client libraries including APIs for:Publishing and subscribing to ROS topicsRequesting and replying ROS services (synchronous (C++ only) and asynchronous)Getting and setting ROS parameters (C++ only, synchronous and asynchronous)Timer callbacksSupport for interoperability between multiple DDS/RTPS implementationseProsima Fast RTPS is our default implementation, and is included in the binary packagesRTI Connext is supported: build from source to try it outWe initially supported PrismTech OpenSplice but support


key: chroma:document
string_value:
it outWe initially supported PrismTech OpenSplice but support for it is currently on holdA graph API for network eventsDistributed discoveryRealtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment)Support for custom allocatorsROS 1 <-> ROS 2 dynamic bridge nodeExecutor threading model (C++ only)Component model to compose nodes at compile / link / runtimeManaged component using a standard lifecycleExtended.msgformat with new features:Bounded arraysDefault valuesKnown issuesWe’re tracking issues in various repositories, but the main entry point is theros2/ros2 issue trackerWe’d like to highlight aknown issuethat we are looking into which doesn’t allow two topics with the same base name but different namespaces to have a different type when usingrmw_connext_cpp.Services with long responses are not working with Fast-RTPS. The fix, while not being part of beta2, is available upstream so you can work around this issue by building from source using Fast-RTPS


key: chroma:document
string_value:
Title: Maintain source checkout

URL: https://docs.ros.org/en/jazzy/Installation/Maintaining

a

Source

Checkout.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Maintain source checkoutNoteFor instructions on maintaining a source checkout of thelatest development versionof ROS 2, refer toMaintaining a source checkout of ROS 2 RollingUpdate your repository listLatest ROS 2 Jazzy branchesUpdate your repositoriesDownload the new source codeRebuild your workspaceInspect your source checkoutIf you have installed ROS 2 from source, there may have been changes made to the source code since the time that you checked it out. To keep your source checkout up to date, you will have to periodically update yourros2.reposfile, download the latest sources, and rebuild your workspace.Update your repository listEach ROS 2 release includes aros2.reposfile that contains the list of repositories and their version for that release.Latest ROS 2 Jazzy branchesIf you wish to checkout the latest code for ROS 2 Jazzy, you can get the relevant repository list by running:LinuxmacOSWindowscd~/ros2_jazzy mv-iros2.reposros2.repos.old


key: chroma:document
string_value:
mv-iros2.reposros2.repos.old wgethttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.reposcd~/ros2_jazzy mv-iros2.reposros2.repos.old wgethttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos# CMDcd\dev\ros2_jazzy curl-skhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos-oros2.repos# PowerShellcd\dev\ros2_jazzy curlhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos-oros2.reposUpdate your repositoriesYou will notice that in theros2.reposfile, each repository has aversionassociated with it that points to a particular commit hash, tag, or branch name. It is possible that these versions refer to new tags/branches that your local copy of the repositories will not recognize as they are out-of-date. Because of this, you should update the repositories that you have already checked out with the following command:vcscustom--argsremoteupdateDownload the new source codeYou should now be able to download the sources associated with the new repository list


key: chroma:document
string_value:
to download the sources associated with the new repository list with:LinuxmacOSWindowsvcsimportsrc<ros2.repos vcspullsrcvcsimportsrc<ros2.repos vcspullsrc# CMDvcsimportsrc<ros2.repos vcspullsrc# PowerShellvcsimport--inputros2.repossrc vcspullsrcRebuild your workspaceNow that the workspace is up to date with the latest sources, remove your previous install and rebuild your workspace with, for example:colconbuild--symlink-installInspect your source checkoutDuring your development you may have deviated from the original state of your workspace from when you imported the repository list. If you wish to know the versions of the set of repositories in your workspace, you can export the information using the following command:LinuxmacOSWindowscd~/ros2_jazzy vcsexportsrc>my_ros2.reposcd~/ros2_jazzy vcsexportsrc>my_ros2.reposcd\dev\ros2_jazzy vcsexportsrc>my_ros2.reposThismy_ros2.reposfile can then be shared with others so that they can reproduce the state of the repositories in your workspace.


key: chroma:document
string_value:
Code Examples:

Language: unknown

cd~/ros2_jazzy

mv

iros2.reposros2.repos.old

wgethttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos

Language: unknown

cd~/ros2_jazzy

mv

iros2.reposros2.repos.old

wgethttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos

Language: unknown

# CMDcd\dev\ros2_jazzy

curl

skhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos

oros2.repos# PowerShellcd\dev\ros2_jazzy

curlhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos

oros2.repos

Language: unknown

vcscustom-

argsremoteupdate

Language: unknown

vcsimportsrc<ros2.repos

vcspullsrc

Language: unknown

vcsimportsrc<ros2.repos

vcspullsrc

Language: unknown

# CMDvcsimportsrc<ros2.repos

vcspullsrc# PowerShellvcsimport-

inputros2.repossrc

vcspullsrc

Language: unknown

colconbuild-

symlink

install

Language: unknown

cd~/ros2_jazzy

vcsexportsrc>my_ros2.repos

Language: unknown

cd~/ros2_jazzy

vcsexportsrc>my_ros2.repos

Language: unknown

cd\dev\ros2_jazzy


key: chroma:document
string_value:
Title: Managing large projects

URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Launch/Using

ROS2

Launch

For

Large

Projects.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Managing large projectsGoal:Learn best practices of managing large projects using ROS 2 launch files.Tutorial level:IntermediateTime:20 minutesContentsBackgroundPrerequisitesIntroductionWriting launch files1 Top-level organization2 Parameters2.1 Setting parameters in the launch file2.2 Loading parameters from YAML file2.3 Using wildcards in YAML files3 Namespaces4 Reusing nodes5 Parameter overrides6 Remapping7 Config files8 Environment VariablesRunning launch files1 Update setup.py2 Build and runSummaryBackgroundThis tutorial describes some tips for writing launch files for large projects. The focus is on how to structure launch files so they may be reused as much as possible in different situations. Additionally, it covers usage examples of different ROS 2 launch tools, like parameters, YAML files, remappings, namespaces, default arguments, and RViz configs.PrerequisitesThis tutorial uses theturtlesimandturtle_tf2_pypackages. This tutorial also assumes you havecreated a new packageof build


key: chroma:document
string_value:
tutorial also assumes you havecreated a new packageof build typeament_pythoncalledlaunch_tutorial.IntroductionLarge applications on a robot typically involve several interconnected nodes, each of which can have many parameters. Simulation of multiple turtles in the turtle simulator can serve as a good example. The turtle simulation consists of multiple turtle nodes, the world configuration, and the TF broadcaster and listener nodes. Between all of the nodes, there are a large number of ROS parameters that affect the behavior and appearance of these nodes. ROS 2 launch files allow us to start all nodes and set corresponding parameters in one place. By the end of a tutorial, you will build thelaunch_turtlesim_launch.pylaunch file in thelaunch_tutorialpackage. This launch file will bring up different nodes responsible for the simulation of two turtlesim simulations, starting TF broadcasters and listener, loading parameters, and launching an RViz configuration. In this tutorial, we’ll go over this launch file


key: chroma:document
string_value:
configuration. In this tutorial, we’ll go over this launch file and all related features used.Writing launch files1 Top-level organizationOne of the aims in the process of writing launch files should be making them as reusable as possible. This could be done by clustering related nodes and configurations into separate launch files. Afterwards, a top-level launch file dedicated to a specific configuration could be written. This would allow moving between identical robots to be done without changing the launch files at all. Even a change such as moving from a real robot to a simulated one can be done with only a few changes.We will now go over the top-level launch file structure that makes this possible. Firstly, we will create a launch file that will call separate launch files. To do this, let’s create alaunch_turtlesim_launch.pyfile in the/launchfolder of


key: chroma:document
string_value:
ourlaunch_tutorialpackage.importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcedefgenerate_launch_description():turtlesim_world_1=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_1_launch.py']))turtlesim_world_2=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_2_launch.py']))broadcaster_listener_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/broadcaster_listener_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)mimic_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/mimi


key: chroma:document
string_value:
(get_package_share_directory('launch_tutorial'),'launch'),'/mimic_launch.py']))fixed_frame_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/fixed_broadcaster_launch.py']))rviz_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_rviz_launch.py']))returnLaunchDescription([turtlesim_world_1,turtlesim_world_2,broadcaster_listener_nodes,mimic_node,fixed_frame_node,rviz_node])This


key: chroma:document
string_value:
launch file includes a set of other launch files. Each of these included launch files contains nodes, parameters, and possibly, nested includes, which pertain to one part of the system. To be exact, we launch two turtlesim simulation worlds, TF broadcaster, TF listener, mimic, fixed frame broadcaster, and RViz nodes.NoteDesign Tip: Top-level launch files should be short, consist of includes to other files corresponding to subcomponents of the application, and commonly changed parameters.Writing launch files in the following manner makes it easy to swap out one piece of the system, as we’ll see later. However, there are cases when some nodes or launch files have to be launched separately due to performance and usage reasons.NoteDesign tip: Be aware of the tradeoffs when deciding how many top-level launch files your application requires.2 Parameters2.1 Setting parameters in the launch fileWe will begin by writing a launch file that will start our first turtlesim simulation. First, create a new file


key: chroma:document
string_value:
start our first turtlesim simulation. First, create a new file calledturtlesim_world_1_launch.py.fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportLaunchConfiguration,TextSubstitutionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():background_r_launch_arg=DeclareLaunchArgument('background_r',default_value=TextSubstitution(text='0'))background_g_launch_arg=DeclareLaunchArgument('background_g',default_value=TextSubstitution(text='84'))background_b_launch_arg=DeclareLaunchArgument('background_b',default_value=TextSubstitution(text='122'))returnLaunchDescription([background_r_launch_arg,background_g_launch_arg,background_b_launch_arg,Node(package='turtlesim',executable='turtlesim_node',name='sim',parameters=[{'background_r':LaunchConfiguration('background_r'),'background_g':LaunchConfiguration('background_g'),'background_b':LaunchConfiguration('background_b'),}]),])This launch file starts theturtlesim_nodenode, which starts the turtlesim


key: chroma:document
string_value:
file starts theturtlesim_nodenode, which starts the turtlesim simulation, with simulation configuration parameters that are defined and passed to the nodes.2.2 Loading parameters from YAML fileIn the second launch, we will start a second turtlesim simulation with a different configuration. Now create aturtlesim_world_2_launch.pyfile.importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():config=os.path.join(get_package_share_directory('launch_tutorial'),'config','turtlesim.yaml')returnLaunchDescription([Node(package='turtlesim',executable='turtlesim_node',namespace='turtlesim2',name='sim',parameters=[config])])This launch file will launch the sameturtlesim_nodewith parameter values that are loaded directly from the YAML configuration file. Defining arguments and parameters in YAML files make it easy to store and load a large number of variables. In addition, YAML files can be easily exported


key: chroma:document
string_value:
of variables. In addition, YAML files can be easily exported from the currentros2paramlist. To learn how to do that, refer to theUnderstand parameterstutorial.Let’s now create a configuration file,turtlesim.yaml, in the/configfolder of our package, which will be loaded by our launch file./turtlesim2/sim:ros__parameters:background_b:255background_g:86background_r:150To learn more about using parameters and using YAML files, take a look at theUnderstand parameterstutorial.2.3 Using wildcards in YAML filesThere are cases when we want to set the same parameters in more than one node. These nodes could have different namespaces or names but still have the same parameters. Defining separate YAML files that explicitly define namespaces and node names is not efficient. A solution is to use wildcard characters, which act as substitutions for unknown characters in a text value, to apply parameters to several different nodes.Now let’s create a newturtlesim_world_3_launch.pyfile similar toturtlesim_world_2_launch.pyto


key: chroma:document
string_value:
similar toturtlesim_world_2_launch.pyto include one moreturtlesim_nodenode....Node(package='turtlesim',executable='turtlesim_node',namespace='turtlesim3',name='sim',parameters=[config])Loading the same YAML file, however, will not affect the appearance of the third turtlesim world. The reason is that its parameters are stored under another namespace as shown below:/turtlesim3/sim:background_bbackground_gbackground_rTherefore, instead of creating a new configuration for the same node that use the same parameters, we can use wildcards syntax./**will assign all the parameters in every node, despite differences in node names and namespaces.We will now update theturtlesim.yaml, in the/configfolder in the following manner:/**:ros__parameters:background_b:255background_g:86background_r:150Now include theturtlesim_world_3_launch.pylaunch description in our main launch file. Using that configuration file in our launch descriptions will assignbackground_b,background_g, andbackground_rparameters to specified values


key: chroma:document
string_value:
andbackground_rparameters to specified values inturtlesim3/simandturtlesim2/simnodes.3 NamespacesAs you may have noticed, we have defined the namespace for the turlesim world in theturtlesim_world_2_launch.pyfile. Unique namespaces allow the system to start two similar nodes without node name or topic name conflicts.namespace='turtlesim2',However, if the launch file contains a large number of nodes, defining namespaces for each of them can become tedious. To solve that issue, thePushROSNamespaceaction can be used to define the global namespace for each launch file description. Every nested node will inherit that namespace automatically.AttentionPushROSNamespace has to be the first Action in the list for the following actions to apply the namespaceTo do that, firstly, we need to remove thenamespace='turtlesim2'line from theturtlesim_world_2_launch.pyfile. Afterwards, we need to update thelaunch_turtlesim_launch.pyto include the following


key: chroma:document
string_value:
to update thelaunch_turtlesim_launch.pyto include the following lines:fromlaunch.actionsimportGroupActionfromlaunch_ros.actionsimportPushROSNamespace...turtlesim_world_2=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_2_launch.py']))turtlesim_world_2_with_namespace=GroupAction(actions=[PushROSNamespace('turtlesim2'),turtlesim_world_2,])Finally, we replace theturtlesim_world_2toturtlesim_world_2_with_namespacein thereturnLaunchDescriptionstatement. As a result, each node in theturtlesim_world_2_launch.pylaunch description will have aturtlesim2namespace.4 Reusing nodesNow create abroadcaster_listener_launch.pyfile.fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportLaunchConfigurationfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([DeclareLaunchArgument('target_frame',default_value='turtle1',description='Target frame


key: chroma:document
string_value:
frame name.'),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster1',parameters=[{'turtlename':'turtle1'}]),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster2',parameters=[{'turtlename':'turtle2'}]),Node(package='turtle_tf2_py',executable='turtle_tf2_listener',name='listener',parameters=[{'target_frame':LaunchConfiguration('target_frame')}]),])In this file, we have declared thetarget_framelaunch argument with a default value ofturtle1. The default value means that the launch file can receive an argument to forward to its nodes, or in case the argument is not provided, it will pass the default value to its nodes.Afterwards, we use theturtle_tf2_broadcasternode two times using different names and parameters during launch. This allows us to duplicate the same node without conflicts.We also start aturtle_tf2_listenernode and set itstarget_frameparameter that we declared and acquired above.5 Parameter overridesRecall that we called


key: chroma:document
string_value:
and acquired above.5 Parameter overridesRecall that we called thebroadcaster_listener_launch.pyfile in our top-level launch file. In addition to that, we have passed ittarget_framelaunch argument as shown below:broadcaster_listener_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/broadcaster_listener_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)This syntax allows us to change the default goal target frame tocarrot1. If you would liketurtle2to followturtle1instead of thecarrot1, just remove the line that defineslaunch_arguments. This will assigntarget_frameits default value, which isturtle1.6 RemappingNow create


key: chroma:document
string_value:
default value, which isturtle1.6 RemappingNow create amimic_launch.pyfile.fromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose','/turtle2/pose'),('/output/cmd_vel','/turtlesim2/turtle1/cmd_vel'),])])This launch file will start themimicnode, which will give commands to one turtlesim to follow the other. The node is designed to receive the target pose on the topic/input/pose. In our case, we want to remap the target pose from/turtle2/posetopic. Finally, we remap the/output/cmd_veltopic to/turtlesim2/turtle1/cmd_vel. This wayturtle1in ourturtlesim2simulation world will followturtle2in our initial turtlesim world.7 Config filesLet’s now create a file


key: chroma:document
string_value:
initial turtlesim world.7 Config filesLet’s now create a file calledturtlesim_rviz_launch.py.importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():rviz_config=os.path.join(get_package_share_directory('turtle_tf2_py'),'rviz','turtle_rviz.rviz')returnLaunchDescription([Node(package='rviz2',executable='rviz2',name='rviz2',arguments=['-d',rviz_config])])This launch file will start the RViz with the configuration file defined in theturtle_tf2_pypackage. This RViz configuration will set the world frame, enable TF visualization, and start RViz with a top-down view.8 Environment VariablesLet’s now create the last launch file calledfixed_broadcaster_launch.pyin our


key: chroma:document
string_value:
the last launch file calledfixed_broadcaster_launch.pyin our package.fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportEnvironmentVariable,LaunchConfigurationfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([DeclareLaunchArgument('node_prefix',default_value=[EnvironmentVariable('USER'),'_'],description='prefix for node name'),Node(package='turtle_tf2_py',executable='fixed_frame_tf2_broadcaster',name=[LaunchConfiguration('node_prefix'),'fixed_broadcaster'],),])This launch file shows the way environment variables can be called inside the launch files. Environment variables can be used to define or push namespaces for distinguishing nodes on different computers or robots.NoteIf you are running the launch file where theUSERenvironment variable is not defined (like in the ROS docker file), then you can replace theEnvironmentVariable('USER')above with any other word of your liking.Running launch files1 Update


key: chroma:document
string_value:
any other word of your liking.Running launch files1 Update setup.pyOpensetup.pyand add the following lines so that the launch files from thelaunch/folder and configuration file from theconfig/would be installed. Thedata_filesfield should now look like this:importosfromglobimportglobfromsetuptoolsimportsetup...data_files=[...(os.path.join('share',package_name,'launch'),glob(os.path.join('launch','*launch.[pxy][yma]*'))),(os.path.join('share',package_name,'config'),glob(os.path.join('config','*.yaml'))),(os.path.join('share',package_name,'rviz'),glob(os.path.join('config','*.rviz'))),],2 Build and runTo finally see the result of our code, build the package and launch the top-level launch file using the following command:ros2 launch launch_tutorial launch_turtlesim_launch.pyYou will now see the two turtlesim simulations started. There are two turtles in the first one and one in the second one. In the first simulation,turtle2is spawned in the bottom-left part of the world. Its aim is to reach thecarrot1frame


key: chroma:document
string_value:
part of the world. Its aim is to reach thecarrot1frame which is five meters away on the x-axis relative to theturtle1frame.Theturtlesim2/turtle1in the second is designed to mimic the behavior of theturtle2.If you want to control theturtle1, run the teleop node.ros2 run turtlesim turtle_teleop_keyAs a result, you will see a similar picture:In addition to that, the RViz should have started. It will show all turtle frames relative to theworldframe, whose origin is at the bottom-left corner.SummaryIn this tutorial, you learned about various tips and practices of managing large projects using ROS 2 launch files.


key: chroma:document
string_value:
importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch.actionsimportIncludeLaunchDescriptionfromlaunch.launch_description_sourcesimportPythonLaunchDescriptionSourcedefgenerate_launch_description():turtlesim_world_1=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_1_launch.py']))turtlesim_world_2=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_2_launch.py']))broadcaster_listener_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/broadcaster_listener_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)mimic_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/mimic_launch.py']))fixed_frame


key: chroma:document
string_value:
ry('launch_tutorial'),'launch'),'/mimic_launch.py']))fixed_frame_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/fixed_broadcaster_launch.py']))rviz_node=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_rviz_launch.py']))returnLaunchDescription([turtlesim_world_1,turtlesim_world_2,broadcaster_listener_nodes,mimic_node,fixed_frame_node,rviz_node])


key: chroma:document
string_value:
Language: unknown

fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportLaunchConfiguration,TextSubstitutionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():background_r_launch_arg=DeclareLaunchArgument('background_r',default_value=TextSubstitution(text='0'))background_g_launch_arg=DeclareLaunchArgument('background_g',default_value=TextSubstitution(text='84'))background_b_launch_arg=DeclareLaunchArgument('background_b',default_value=TextSubstitution(text='122'))returnLaunchDescription([background_r_launch_arg,background_g_launch_arg,background_b_launch_arg,Node(package='turtlesim',executable='turtlesim_node',name='sim',parameters=[{'background_r':LaunchConfiguration('background_r'),'background_g':LaunchConfiguration('background_g'),'background_b':LaunchConfiguration('background_b'),}]),])

Language: unknown


key: chroma:document
string_value:
Language: unknown

importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():config=os.path.join(get_package_share_directory('launch_tutorial'),'config','turtlesim.yaml')returnLaunchDescription([Node(package='turtlesim',executable='turtlesim_node',namespace='turtlesim2',name='sim',parameters=[config])])

Language: unknown

/turtlesim2/sim:ros__parameters:background_b:255background_g:86background_r:150

Language: unknown

...Node(package='turtlesim',executable='turtlesim_node',namespace='turtlesim3',name='sim',parameters=[config])

Language: unknown

/turtlesim3/sim:background_bbackground_gbackground_r

Language: unknown

/*

:ros__parameters:background_b:255background_g:86background_r:150

Language: unknown

namespace='turtlesim2',

Language: unknown


key: chroma:document
string_value:
Language: unknown

namespace='turtlesim2',

Language: unknown

fromlaunch.actionsimportGroupActionfromlaunch_ros.actionsimportPushROSNamespace...turtlesim_world_2=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/turtlesim_world_2_launch.py']))turtlesim_world_2_with_namespace=GroupAction(actions=[PushROSNamespace('turtlesim2'),turtlesim_world_2,])

Language: unknown


key: chroma:document
string_value:
Language: unknown

fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportLaunchConfigurationfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([DeclareLaunchArgument('target_frame',default_value='turtle1',description='Target frame name.'),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster1',parameters=[{'turtlename':'turtle1'}]),Node(package='turtle_tf2_py',executable='turtle_tf2_broadcaster',name='broadcaster2',parameters=[{'turtlename':'turtle2'}]),Node(package='turtle_tf2_py',executable='turtle_tf2_listener',name='listener',parameters=[{'target_frame':LaunchConfiguration('target_frame')}]),])

Language: unknown

broadcaster_listener_nodes=IncludeLaunchDescription(PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('launch_tutorial'),'launch'),'/broadcaster_listener_launch.py']),launch_arguments={'target_frame':'carrot1'}.items(),)

Language: unknown


key: chroma:document
string_value:
Language: unknown

fromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose','/turtle2/pose'),('/output/cmd_vel','/turtlesim2/turtle1/cmd_vel'),])])

Language: unknown

importosfromament_index_python.packagesimportget_package_share_directoryfromlaunchimportLaunchDescriptionfromlaunch_ros.actionsimportNodedefgenerate_launch_description():rviz_config=os.path.join(get_package_share_directory('turtle_tf2_py'),'rviz','turtle_rviz.rviz')returnLaunchDescription([Node(package='rviz2',executable='rviz2',name='rviz2',arguments=['

d',rviz_config])])

Language: unknown


key: chroma:document
string_value:
d',rviz_config])])

Language: unknown

fromlaunchimportLaunchDescriptionfromlaunch.actionsimportDeclareLaunchArgumentfromlaunch.substitutionsimportEnvironmentVariable,LaunchConfigurationfromlaunch_ros.actionsimportNodedefgenerate_launch_description():returnLaunchDescription([DeclareLaunchArgument('node_prefix',default_value=[EnvironmentVariable('USER'),'_'],description='prefix for node name'),Node(package='turtle_tf2_py',executable='fixed_frame_tf2_broadcaster',name=[LaunchConfiguration('node_prefix'),'fixed_broadcaster'],),])

Language: unknown

importosfromglobimportglobfromsetuptoolsimportsetup...data_files=[...(os.path.join('share',package_name,'launch'),glob(os.path.join('launch','

launch.[pxy][yma]

'))),(os.path.join('share',package_name,'config'),glob(os.path.join('config','

.yaml'))),(os.path.join('share',package_name,'rviz'),glob(os.path.join('config','

.rviz'))),],

Language: unknown

ros2 launch launch_tutorial launch_turtlesim_launch.py

Language: unknown


key: chroma:document
string_value:
Title: Tf2

URL: https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Tf2.html

Section: Installation

--------------------------------------------------------------------------------

Tf2Table of ContentsOverviewProperties of tf2TutorialsPaperOverviewtf2 is the transform library, which lets the user keep track of multiple coordinate frames over time.

tf2 maintains the relationship between coordinate frames in a tree structure buffered in time and lets the user transform points, vectors, etc. between any two coordinate frames at any desired point in time.Properties of tf2A robotic system typically has many 3D coordinate frames that change over time, such as a world frame, base frame, gripper frame, head frame, etc.


key: chroma:document
string_value:
tf2 keeps track of all these frames over time, and allows you to ask questions like:Where was the head frame relative to the world frame 5 seconds ago?What is the pose of the object in my gripper relative to my base?What is the current pose of the base frame in the map frame?tf2 can operate in a distributed system.

This means all the information about the coordinate frames of a robot is available to all ROS 2 components on any computer in the system.

tf2 can have every component in your distributed system build its own transform information database or have a central node that gathers and stores all transform information.TutorialsWe created a set oftutorialsthat walks you through using tf2, step by step.

You can get started on theintroduction to tf2tutorial.


key: chroma:document
string_value:
You can get started on theintroduction to tf2tutorial.

For a complete list of all tf2 and tf2-related tutorials check out thetutorialspage.There are essentially two main tasks that any user would use tf2 for, listening for transforms and broadcasting transforms.If you want to use tf2 to transform between coordinate frames, your nodes will need to listen for transforms.

What you will do is receive and buffer all coordinate frames that are broadcasted in the system, and query for specific transforms between frames.

Check out the “Writing a listener” tutorial(Python)(C++)to learn more.To extend the capabilities of a robot, you will need to start broadcasting transforms.

Broadcasting transforms means to send out the relative pose of coordinate frames to the rest of the system.

A system can have many broadcasters that each provide information about a different part of the robot.


key: chroma:document
string_value:
Check out the “Writing a broadcaster” tutorial(Python)(C++)to learn more.In addition to that, tf2 can broadcast static transforms that do not change over time.

This mainly saves storage and lookup time, but also reduces the publishing overhead.

You should note that static transforms are published once and assumed to not change, so no history is stored.

If you want to define static transforms in your tf2 tree, take a look at the “Writing a static broadcaster”(Python)(C++)tutorial.You can also learn how to add fixed and dynamic frames to your tf2 tree in the “Adding a frame”(Python)(C++)tutorial.Once you are finished with the basic tutorials, you can move on to learn about tf2 and time.

The tf2 and time tutorial(C++)teaches the basic principles of tf2 and time.

The advanced tutorial about tf2 and time(C++)teaches the principles of time traveling with tf2.PaperThere is a paper on tf2 presented at TePRA 2013:tf: The transform library.


key: chroma:document
string_value:
Title: Executors

URL: https://docs.ros.org/en/jazzy/Concepts/Intermediate/About

Executors.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
ExecutorsTable of ContentsOverviewBasic useTypes of ExecutorsCallback groupsScheduling semanticsOutlookFurther informationOverviewExecution management in ROS 2 is handled by Executors. An Executor uses one or more threads of the underlying operating system to invoke the callbacks of subscriptions, timers, service servers, action servers, etc. on incoming messages and events. The explicit Executor class (inexecutor.hppin rclcpp, inexecutors.pyin rclpy, or inexecutor.hin rclc) provides more control over execution management than the spin mechanism in ROS 1, although the basic API is very similar.In the following, we focus on the C++ Client Libraryrclcpp.Basic useIn the simplest case, the main thread is used for processing the incoming messages and events of a Node by callingrclcpp::spin(..)as follows:intmain(intargc,char*argv[]){// Some initialization.rclcpp::init(argc,argv);...// Instantiate a node.rclcpp::Node::SharedPtrnode=...// Run the executor.rclcpp::spin(node);// Shutdown and exit....return0;}The


key: chroma:document
string_value:
Shutdown and exit....return0;}The call tospin(node)basically expands to an instantiation and invocation of the Single-Threaded Executor, which is the simplest Executor:rclcpp::executors::SingleThreadedExecutorexecutor;executor.add_node(node);executor.spin();By invokingspin()of the Executor instance, the current thread starts querying the rcl and middleware layers for incoming messages and other events and calls the corresponding callback functions until the node shuts down. In order not to counteract the QoS settings of the middleware, an incoming message is not stored in a queue on the Client Library layer but kept in the middleware until it is taken for processing by a callback function. (This is a crucial difference to ROS 1.) Await setis used to inform the Executor about available messages on the middleware layer, with one binary flag per queue. Thewait setis also used to detect when timers expire.The Single-Threaded Executor is also used by the container process forcomponents, i.e. in all cases where


key: chroma:document
string_value:
by the container process forcomponents, i.e. in all cases where nodes are created and executed without an explicit main function.Types of ExecutorsCurrently, rclcpp provides three Executor types, derived from a shared parent class:TheMulti-Threaded Executorcreates a configurable number of threads to allow for processing multiple messages or events in parallel. TheStatic Single-Threaded Executoroptimizes the runtime costs for scanning the structure of a node in terms of subscriptions, timers, service servers, action servers, etc. It performs this scan only once when the node is added, while the other two executors regularly scan for such changes. Therefore, the Static Single-Threaded Executor should be used only with nodes that create all subscriptions, timers, etc. during initialization.All three executors can be used with multiple nodes by callingadd_node(..)for each


key: chroma:document
string_value:
can be used with multiple nodes by callingadd_node(..)for each node.rclcpp::Node::SharedPtrnode1=...rclcpp::Node::SharedPtrnode2=...rclcpp::Node::SharedPtrnode3=...rclcpp::executors::StaticSingleThreadedExecutorexecutor;executor.add_node(node1);executor.add_node(node2);executor.add_node(node3);executor.spin();In the above example, the one thread of a Static Single-Threaded Executor is used to serve three nodes together. In case of a Multi-Threaded Executor, the actual parallelism depends on the callback groups.Callback groupsROS 2 allows organizing the callbacks of a node in groups. In rclcpp, such acallback groupcan be created by thecreate_callback_groupfunction of the Node class. In rclpy, the same is done by calling the constructor of the specific callback group type. The callback group must be stored throughout execution of the node (eg. as a class member), or otherwise the executor won’t be able to trigger the callbacks. Then, this callback group can be specified when creating a subscription, timer,


key: chroma:document
string_value:
group can be specified when creating a subscription, timer, etc. - for example by the subscription options:C++Pythonmy_callback_group=create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);rclcpp::SubscriptionOptionsoptions;options.callback_group=my_callback_group;my_subscription=create_subscription<Int32>("/topic",rclcpp::SensorDataQoS(),callback,options);my_callback_group=MutuallyExclusiveCallbackGroup()my_subscription=self.create_subscription(Int32,"/topic",self.callback,qos_profile=1,callback_group=my_callback_group)All subscriptions, timers, etc. that are created without the indication of a callback group are assigned to thedefault callback group. The default callback group can be queried viaNodeBaseInterface::get_default_callback_group()in rclcpp and byNode.default_callback_groupin rclpy.There are two types of callback groups, where the type has to be specified at instantiation time:Mutually exclusive:Callbacks of this group must not be executed in parallel.Reentrant:Callbacks of this


key: chroma:document
string_value:
must not be executed in parallel.Reentrant:Callbacks of this group may be executed in parallel.Callbacks of different callback groups may always be executed in parallel. The Multi-Threaded Executor uses its threads as a pool to process as many callbacks as possible in parallel according to these conditions. For tips on how to use callback groups efficiently, seeUsing Callback Groups.The Executor base class in rclcpp also has the functionadd_callback_group(..), which allows distributing callback groups to different Executors. By configuring the underlying threads using the operating system scheduler, specific callbacks can be prioritized over other callbacks. For example, the subscriptions and timers of a control loop can be prioritized over all other subscriptions and standard services of a node. Theexamples_rclcpp_cbg_executor packageprovides a demo of this mechanism.Scheduling semanticsIf the processing time of the callbacks is shorter than the period with which messages and events occur, the Executor


key: chroma:document
string_value:
the period with which messages and events occur, the Executor basically processes them in FIFO order. However, if the processing time of some callbacks is longer, messages and events will be queued on the lower layers of the stack. The wait set mechanism reports only very little information about these queues to the Executor. In detail, it only reports whether there are any messages for a certain topic or not. The Executor uses this information to process the messages (including services and actions) in a round-robin fashion - but not in FIFO order. The following flow diagram visualizes this scheduling semantics.This semantics was first described in apaper by Casini et al. at ECRTS 2019. (Note: The paper also explains that timer events are prioritized over all other messages.This prioritization was removed in Eloquent.)OutlookWhile the three Executors of rclcpp work well for most applications, there are some issues that make them not suitable for real-time applications, which require well-defined execution


key: chroma:document
string_value:
real-time applications, which require well-defined execution times, determinism, and custom control over the execution order. Here is a summary of some of these issues:Complex and mixed scheduling semantics. Ideally you want well defined scheduling semantics to perform a formal timing analysis.Callbacks may suffer from priority inversion. Higher priority callbacks may be blocked by lower priority callbacks.No explicit control over the callbacks execution order.No built-in control over triggering for specific topics.Additionally, the executor overhead in terms of CPU and memory usage is considerable. The Static Single-Threaded Executor reduces this overhead greatly but it might not be enough for some applications.These issues have been partially addressed by the following developments:rclcpp WaitSet: TheWaitSetclass of rclcpp allows waiting directly on subscriptions, timers, service servers, action servers, etc. instead of using an Executor. It can be used to implement deterministic, user-defined processing


key: chroma:document
string_value:
can be used to implement deterministic, user-defined processing sequences, possibly processing multiple messages from different subscriptions together. Theexamples_rclcpp_wait_set packageprovides several examples for the use of this user-level wait set mechanism.rclc Executor: This Executor from the C Client Libraryrclc, developed for micro-ROS, gives the user fine-grained control over the execution order of callbacks and allows for custom trigger conditions to activate callbacks. Furthermore, it implements ideas of the Logical Execution Time (LET) semantics.Further informationMichael Pöhnl et al.:“ROS 2 Executor: How to make it efficient, real-time and deterministic?”. Workshop at ROS World 2021. Virtual event. 19 October 2021.Ralph Lange:“Advanced Execution Management with ROS 2”. ROS Industrial Conference. Virtual event. 16 December 2020.Daniel Casini, Tobias Blass, Ingo Lütkebohle, and Björn Brandenburg:“Response-Time Analysis of ROS 2 Processing Chains under Reservation-Based Scheduling”, Proc. of 31st


key: chroma:document
string_value:
Chains under Reservation-Based Scheduling”, Proc. of 31st ECRTS 2019, Stuttgart, Germany, July 2019.


key: chroma:document
string_value:
Code Examples:

Language: unknown intmain(intargc,char*argv[]){// Some initialization.rclcpp::init(argc,argv);...// Instantiate a node.rclcpp::Node::SharedPtrnode=...// Run the executor.rclcpp::spin(node);// Shutdown and exit....return0;}

Language: unknown

rclcpp::executors::SingleThreadedExecutorexecutor;executor.add_node(node);executor.spin();

Language: unknown

rclcpp::Node::SharedPtrnode1=...rclcpp::Node::SharedPtrnode2=...rclcpp::Node::SharedPtrnode3=...rclcpp::executors::StaticSingleThreadedExecutorexecutor;executor.add_node(node1);executor.add_node(node2);executor.add_node(node3);executor.spin();

Language: unknown

my_callback_group=create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);rclcpp::SubscriptionOptionsoptions;options.callback_group=my_callback_group;my_subscription=create_subscription<Int32>("/topic",rclcpp::SensorDataQoS(),callback,options);

Language: unknown


key: chroma:document
string_value:
Language: unknown

my_callback_group=MutuallyExclusiveCallbackGroup()my_subscription=self.create_subscription(Int32,"/topic",self.callback,qos_profile=1,callback_group=my_callback_group)


key: chroma:document
string_value:
Title: Understanding parameters

URL: https://docs.ros.org/en/jazzy/Tutorials/Beginner

CLI

Tools/Understanding

ROS2

Parameters/Understanding

ROS2

Parameters.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Understanding parametersGoal:Learn how to get, set, save and reload parameters in ROS 2.Tutorial level:BeginnerTime:5 minutesContentsBackgroundPrerequisitesTasks1 Setup2 ros2 param list3 ros2 param get4 ros2 param set5 ros2 param dump6 ros2 param load7 Load parameter file on node startupSummaryNext stepsBackgroundA parameter is a configuration value of a node. You can think of parameters as node settings. A node can store parameters as integers, floats, booleans, strings, and lists. In ROS 2, each node maintains its own parameters. For more background on parameters, please seethe concept document.PrerequisitesThis tutorial uses theturtlesim package.As always, don’t forget to source ROS 2 inevery new terminal you open.Tasks1 SetupStart up the two turtlesim nodes,/turtlesimand/teleop_turtle.Open a new terminal and run:ros2 run turtlesim turtlesim_nodeOpen another terminal and run:ros2 run turtlesim turtle_teleop_key2 ros2 param listTo see the parameters belonging to your nodes, open a new terminal and


key: chroma:document
string_value:
the parameters belonging to your nodes, open a new terminal and enter the command:ros2 param listYou will see the node namespaces,/teleop_turtleand/turtlesim, followed by each node’s parameters:/teleop_turtle:qos_overrides./parameter_events.publisher.depthqos_overrides./parameter_events.publisher.durabilityqos_overrides./parameter_events.publisher.historyqos_overrides./parameter_events.publisher.reliabilityscale_angularscale_linearuse_sim_time/turtlesim:background_bbackground_gbackground_rqos_overrides./parameter_events.publisher.depthqos_overrides./parameter_events.publisher.durabilityqos_overrides./parameter_events.publisher.historyqos_overrides./parameter_events.publisher.reliabilityuse_sim_timeEvery node has the parameteruse_sim_time; it’s not unique to turtlesim.Based on their names, it looks like/turtlesim’s parameters determine the background color of the turtlesim window using RGB color values.To determine a parameter’s type, you can useros2paramget.3 ros2 param getTo display the type and current


key: chroma:document
string_value:
ros2 param getTo display the type and current value of a parameter, use the command:ros2 param get <node_name> <parameter_name>Let’s find out the current value of/turtlesim’s parameterbackground_g:ros2 param get /turtlesim background_gWhich will return the value:Integer value is: 86Now you knowbackground_gholds an integer value.If you run the same command onbackground_randbackground_b, you will get the values69and255, respectively.4 ros2 param setTo change a parameter’s value at runtime, use the command:ros2 param set <node_name> <parameter_name> <value>Let’s change/turtlesim’s background color:ros2 param set /turtlesim background_r 150Your terminal should return the message:Set parameter successfulAnd the background of your turtlesim window should change colors:Setting parameters with thesetcommand will only change them in your current session, not permanently. However, you can save your settings and reload them the next time you start a node.5 ros2 param dumpYou can view all of a node’s current


key: chroma:document
string_value:
a node.5 ros2 param dumpYou can view all of a node’s current parameter values by using the command:ros2 param dump <node_name>The command prints to the standard output (stdout) by default but you can also redirect the parameter values into a file to save them for later. To save your current configuration of/turtlesim’s parameters into the fileturtlesim.yaml, enter the command:ros2 param dump /turtlesim > turtlesim.yamlYou will find a new file in the current working directory your shell is running in. If you open this file, you’ll see the following content:/turtlesim:ros__parameters:background_b:255background_g:86background_r:150qos_overrides:/parameter_events:publisher:depth:1000durability:volatilehistory:keep_lastreliability:reliableuse_sim_time:falseDumping parameters comes in handy if you want to reload the node with the same parameters in the future.6 ros2 param loadYou can load parameters from a file to a currently running node using the command:ros2 param load <node_name> <parameter_file>To load


key: chroma:document
string_value:
the command:ros2 param load <node_name> <parameter_file>To load theturtlesim.yamlfile generated withros2paramdumpinto/turtlesimnode’s parameters, enter the command:ros2 param load /turtlesim turtlesim.yamlYour terminal will return the message:Set parameter background_b successfulSet parameter background_g successfulSet parameter background_r successfulSet parameter qos_overrides./parameter_events.publisher.depth failed: parameter 'qos_overrides./parameter_events.publisher.depth' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.durability failed: parameter 'qos_overrides./parameter_events.publisher.durability' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.history failed: parameter 'qos_overrides./parameter_events.publisher.history' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.reliability failed: parameter 'qos_overrides./parameter_events.publisher.reliability' cannot be


key: chroma:document
string_value:
cannot be set because it is read-onlySet parameter use_sim_time successfulNoteRead-only parameters can only be modified at startup and not afterwards, that is why there are some warnings for the “qos_overrides” parameters.7 Load parameter file on node startupTo start the same node using your saved parameter values, use:ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>This is the same command you always use to start turtlesim, with the added flags--ros-argsand--params-file, followed by the file you want to load.Stop your running turtlesim node, and try reloading it with your saved parameters, using:ros2 run turtlesim turtlesim_node --ros-args --params-file turtlesim.yamlThe turtlesim window should appear as usual, but with the purple background you set earlier.NoteWhen a parameter file is used at node startup, all parameters, including the read-only ones, will be updated.SummaryNodes have parameters to define their default configuration values. You cangetandsetparameter values


key: chroma:document
string_value:
default configuration values. You cangetandsetparameter values from the command line. You can also save the parameter settings to a file to reload them in a future session.Next stepsJumping back to ROS 2 communication methods, in the next tutorial you’ll learn aboutactions.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtle_teleop_key

Language: unknown

ros2 param list

Language: unknown

/teleop_turtle:qos_overrides./parameter_events.publisher.depthqos_overrides./parameter_events.publisher.durabilityqos_overrides./parameter_events.publisher.historyqos_overrides./parameter_events.publisher.reliabilityscale_angularscale_linearuse_sim_time/turtlesim:background_bbackground_gbackground_rqos_overrides./parameter_events.publisher.depthqos_overrides./parameter_events.publisher.durabilityqos_overrides./parameter_events.publisher.historyqos_overrides./parameter_events.publisher.reliabilityuse_sim_time

Language: unknown ros2 param get <node_name> <parameter_name>

Language: unknown ros2 param get /turtlesim background_g

Language: unknown

Integer value is: 86

Language: unknown ros2 param set <node_name> <parameter_name> <value>

Language: unknown ros2 param set /turtlesim background_r 150

Language: unknown


key: chroma:document
string_value:
Language: unknown

Set parameter successful

Language: unknown

ros2 param dump <node_name>

Language: unknown ros2 param dump /turtlesim > turtlesim.yaml

Language: unknown

/turtlesim:ros__parameters:background_b:255background_g:86background_r:150qos_overrides:/parameter_events:publisher:depth:1000durability:volatilehistory:keep_lastreliability:reliableuse_sim_time:false

Language: unknown ros2 param load <node_name> <parameter_file>

Language: unknown ros2 param load /turtlesim turtlesim.yaml


key: chroma:document
string_value:
Language: unknown ros2 param load /turtlesim turtlesim.yaml

Language: unknown Set parameter background_b successfulSet parameter background_g successfulSet parameter background_r successfulSet parameter qos_overrides./parameter_events.publisher.depth failed: parameter 'qos_overrides./parameter_events.publisher.depth' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.durability failed: parameter 'qos_overrides./parameter_events.publisher.durability' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.history failed: parameter 'qos_overrides./parameter_events.publisher.history' cannot be set because it is read-onlySet parameter qos_overrides./parameter_events.publisher.reliability failed: parameter 'qos_overrides./parameter_events.publisher.reliability' cannot be set because it is read-onlySet parameter use_sim_time successful

Language: unknown ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>


key: chroma:document
string_value:
Title: Usingrqt_consoleto view logs

URL: https://docs.ros.org/en/jazzy/Tutorials/Beginner

CLI

Tools/Using

Rqt

Console/Using

Rqt

Console.html

Section: Installation

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Usingrqt_consoleto view logsGoal:Get to knowrqt_console, a tool for introspecting log messages.Tutorial level:BeginnerTime:5 minutesContentsBackgroundPrerequisitesTasks1 Setup2 Messages on rqt_console3 Logger levelsSummaryNext stepsBackgroundrqt_consoleis a GUI tool used to introspect log messages in ROS 2. Typically, log messages show up in your terminal. Withrqt_console, you can collect those messages over time, view them closely and in a more organized manner, filter them, save them and even reload the saved files to introspect at a different time.Nodes use logs to output messages concerning events and status in a variety of ways. Their content is usually informational, for the sake of the user.PrerequisitesYou will needrqt_console and turtlesiminstalled.As always, don’t forget to source ROS 2 inevery new terminal you open.Tasks1 SetupStartrqt_consolein a new terminal with the following command:ros2 run rqt_console rqt_consoleTherqt_consolewindow will open:The first section of the console is where


key: chroma:document
string_value:
will open:The first section of the console is where log messages from your system will display.In the middle you have the option to filter messages by excluding severity levels. You can also add more exclusion filters using the plus-sign button to the right.The bottom section is for highlighting messages that include a string you input. You can add more filters to this section as well.Now startturtlesimin a new terminal with the following command:ros2 run turtlesim turtlesim_node2 Messages on rqt_consoleTo produce log messages forrqt_consoleto display, let’s have the turtle run into the wall. In a new terminal, enter theros2topicpubcommand (discussed in detail in thetopics tutorial) below:ros2 topic pub -r 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}"Since the above command is publishing the topic at a steady rate, the turtle is continuously running into the wall. Inrqt_consoleyou will see the same message with theWarnseverity level


key: chroma:document
string_value:
will see the same message with theWarnseverity level displayed over and over, like so:PressCtrl+Cin the terminal where you ran theros2topicpubcommand to stop your turtle from running into the wall.3 Logger levelsROS 2’s logger levels are ordered by severity:FatalErrorWarnInfoDebugThere is no exact standard for what each level indicates, but it’s safe to assume that:Fatalmessages indicate the system is going to terminate to try to protect itself from detriment.Errormessages indicate significant issues that won’t necessarily damage the system, but are preventing it from functioning properly.Warnmessages indicate unexpected activity or non-ideal results that might represent a deeper issue, but don’t harm functionality outright.Infomessages indicate event and status updates that serve as a visual verification that the system is running as expected.Debugmessages detail the entire step-by-step process of the system execution.The default level isInfo. You will only see messages of the default severity level and


key: chroma:document
string_value:
You will only see messages of the default severity level and more-severe levels.Normally, onlyDebugmessages are hidden because they’re the only level less severe thanInfo. For example, if you set the default level toWarn, you would only see messages of severityWarn,Error, andFatal.3.1 Set the default logger levelYou can set the default logger level when you first run the/turtlesimnode using remapping. Enter the following command in your terminal:ros2 run turtlesim turtlesim_node --ros-args --log-level WARNNow you won’t see the initialInfolevel messages that came up in the console last time you startedturtlesim. That’s becauseInfomessages are lower priority than the new default severity,Warn.Summaryrqt_consolecan be very helpful if you need to closely examine the log messages from your system. You might want to examine log messages for any number of reasons, usually to find out where something went wrong and the series of events leading up to that.Next stepsThe next tutorial will teach you about starting


key: chroma:document
string_value:
that.Next stepsThe next tutorial will teach you about starting multiple nodes at once withROS 2 Launch.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 run rqt_console rqt_console

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown ros2 topic pub -r 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}"

Language: unknown

FatalErrorWarnInfoDebug

Language: unknown ros2 run turtlesim turtlesim_node --ros-args --log-level WARN


key: chroma:document
string_value:
Title: GoalUpdated

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/GoalUpdated.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<GoalUpdated/>

```


key: chroma:document
string_value:
Title: ComputePathToPose

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/ComputePathToPose.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Output Ports

## Example

Code Examples:

Language: unknown

File: ComputePathToPose

```

<ComputePathToPose

goal=

"{goal}"

path=

"{path}"

planner_id=

"GridBased"

server_name=

"ComputePathToPose"

server_timeout=

"10"

error_code_id=

"{compute_path_error_code}"

/>

```


key: chroma:document
string_value:
Title: First

Time Robot Setup Guide

URL: https://docs.nav2.org/setup_guides/index.html#setup

guides

Section: tuning/index.html

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Title: IsStopped

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/IsStopped.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Port

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<IsStopped

velocity_threshold=

"0.01"

duration_stopped=

"1000"

/>

```


key: chroma:document
string_value:
Title: Migration Guides

URL: https://docs.nav2.org/migration/index.html

Section: getting_started/index.html

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Title: Setting Up Odometry

URL: https://docs.nav2.org/setup_guides/odom/setup_odom.html#setup-and-prerequisites

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Odometry Introduction

The odometry system provides a locally accurate estimate of a robot’s pose and velocity based on its motion. The odometry information can be obtained from various sources such as IMU, LIDAR, RADAR, VIO, and wheel encoders. One thing to note is that IMUs drift over time while wheel encoders drift over distance traveled, thus they are often used together to counter each other’s negative characteristics.


key: chroma:document
string_value:
Theodomframe and the transformation associated with it use a robot’s odometry system to publish localization information that is continuous but becomes less accurate over time or distance (depending on the sensor modalities and drift). In spite of this, the information can still be used by the robot to navigate its immediate vicinity (e.g collision avoidance). To obtain consistently accurate odometry information over time, themapframe provides globally accurate information that is used to correct theodomframe.

As discussed in the previous guides and inREP 105, theodomframe is connected to the rest of the system and Nav2 through theodom=>base_linktransform. This transform is published by a tf2 broadcaster or by frameworks such asrobot_localization, which also provide additional functionalities. We will be talking more aboutrobot_localizationin a following section.


key: chroma:document
string_value:
In addition to the requiredodom=>base_linktransform, Nav2 also requires the publishing ofnav_msgs/Odometrymessage because this message provides the velocity information of the robot. In detail, thenav_msgs/Odometrymessage contains the following information:

This message tells us the estimates for the pose and velocity of the robot. Theheadermessage provides the timestamped data in a given coordinate frame. Theposemessage provides the position and orientation of the robot relative to the frame specified inheader.frame_id. Thetwistmessage gives the linear and angular velocity relative to the frame defined inchild_frame_id.

## Setting Up Odometry on your Robot


key: chroma:document
string_value:
## Setting Up Odometry on your Robot

Setting up the odometry system for Nav2 for your physical robot depends a lot on which odometry sensors are available with your robot. Due to the large number of configurations your robot may have, specific setup instructions will not be within the scope of this tutorial. Instead, we will provide some basic examples and useful resources to help you configure your robot for Nav2.

To start, we will use an example of a robot with wheel encoders as its odometry source. Note that wheel encoders are not required for Nav2 but it is common in most setups. The goal in setting up the odometry is to compute the odometry information and publish thenav_msgs/Odometrymessage andodom=>base_linktransform over ROS 2. To calculate this information, you will need to setup some code that will translate wheel encoder information into odometry information, similar to the snippet below:


key: chroma:document
string_value:
Theright_wheel_est_velandleft_wheel_est_velare the estimated velocities of the right and left wheels respectively, and thewheelseparationis the distance between the wheels. The values ofright_wheel_est_velandleft_wheel_est_velcan be obtained by simply getting the changes in the positions of the wheel joints over time. This information can then be used to publish the Nav2 requirements. A basic example on how to do this can be found in the Navigation documentation on odometrylocated here


key: chroma:document
string_value:
An alternative to manually publishing this information that we recommend is through theros2_controlframework. Theros2_controlframework contains various packages for real-time control of robots in ROS 2. For wheel encoders,ros2_controlhas adiff_drive_controller(differential drive controller) under theros2_controllerpackage. Thediff_drive_controllertakes in thegeometry_msgs/Twistmessages published oncmd_veltopic, computes odometry information, and publishesnav_msgs/Odometrymessages onodomtopic. Other packages that deal with different kind of sensors are also available inros2_control.

For other types of sensors such as IMU, VIO, etc, their respective ROS drivers should have documentation on how publish the odometry information. Keep in mind that Nav2 requires thenav_msgs/Odometrymessage andodom=>base_linktransforms to be published and this should be your goal when setting up your odometry system.

## Simulating an Odometry System using Gazebo


key: chroma:document
string_value:
## Simulating an Odometry System using Gazebo

In this section, we will be using Gazebo to simulate the odometry system ofsam_bot, the robot that we built in the previous section of this tutorial series. You may go through that guide first or grab thecomplete source here.

As an overview for this section, we will first setup Gazebo and the necessary packages required to make it work with ROS 2. Next, we will be adding Gazebo plugins, which simulate an IMU sensor and a differential drive odometry system, in order to publishsensor_msgs/Imuandnav_msgs/Odometrymessages respectively. Lastly, we will spawnsam_botin a Gazebo environment and verify the publishedsensor_msgs/Imuandnav_msgs/Odometrymessages over ROS 2.

## Setup and Prerequisites

Gazebois a 3D simulator that allows us to observe how our virtual robot will function in a simulated environment. To start using Gazebo with ROS 2, follow the installation instructions in theGazebo Installation Documentation.


key: chroma:document
string_value:
We also need to install thegazebo_ros_pkgspackage to simulate odometry and control the robot with ROS 2 in Gazebo:

You can test if you have successfully set up your ROS 2 and Gazebo environments by following the instructionsgiven here.

Note that we describedsam_botusing URDF. However, Gazebo usesSimulation Description Format (SDF)to describe a robot in its simulated environment. Fortunately, Gazebo automatically translates compatible URDF files into SDF. The main requirement for the URDF to be compatible with Gazebo is to have an<inertia>element within each<link>element. This requirement is already satisfied in the URDF file ofsam_bot, so it can already be used in Gazebo.

## Adding Gazebo Plugins to a URDF

We will now add the IMU sensor and the differential drive plugins of Gazebo to our URDF. For an overview of the different plugins available in Gazebo, have a look atTutorial: Using Gazebo plugins with ROS.


key: chroma:document
string_value:
For our robot, we will be using theGazeboRosImuSensorwhich is a SensorPlugin. A SensorPlugin must be attached to a link, thus we will create animu_linkto which the IMU sensor will be attached. This link will be referenced under the<gazebo>element. Next, we will set/demo/imuas the topic to which the IMU will be publishing its information, and we will comply withREP145by settinginitalOrientationAsReferencetofalse. We will also add some noise to the sensor configuration using Gazebo’ssensor noise model.

Now, we will set up our IMU sensor plugin according to the description above by adding the following lines before the</robot>line in our URDF:

Now, let us add the differential drive ModelPlugin. We will configure the plugin such thatnav_msgs/Odometrymessages are published on the/demo/odomtopic. The joints of the left and right wheels will be set to the wheel joints ofsam_bot. The wheel separation and wheel diameter are set according to the values of the defined values ofwheel_ygapandwheel_radiusrespectively.


key: chroma:document
string_value:
To include this plugin in our URDF, add the following lines after the</gazebo>tag of the IMU plugin:

## Launch and Build Files

We will now edit our launch file,launch/display.launch.py, to spawnsam_botin Gazebo. Since we will be simulating our robot, we can remove the GUI for the joint state publisher by deleting the following lines inside thegenerate_launch_description():

Remove the followingguiparam:

Remove the condition and parameters. Add arguments to thejoint_state_publisher_node:

Next, openpackage.xmland delete the line:

To launch Gazebo, add the following before thejoint_state_publisher_node,line indisplay.launch.py

We will now add a node that spawnssam_botin Gazebo. Openlaunch/display.launch.pyagain and paste the following lines before thereturnlaunch.LaunchDescription([line.

Then add the linespawn_entity,before therviz_nodeline, as shown below.

## Build, Run and Verification

Let us run our package to check if the/demo/imuand/demo/odomtopics are active in the system.


key: chroma:document
string_value:
Navigate to the root of the project and execute the following lines:

Gazebo should launch and you should see a 3D model ofsam_bot:

To see the active topics in the system, open a new terminal and execute:

You should see/demo/imuand/demo/odomin the list of topics.

To see more information about the topics, execute:

You should see an output similar to below:

Observe that the/demo/imutopic publishessensor_msgs/Imutype messages while the/demo/odomtopic publishesnav_msgs/Odometrytype messages. The information being published on these topics come from the gazebo simulation of the IMU sensor and the differential drive respectively. Also note that both topics currently have no subscribers. In the next section, we will create arobot_localizationnode that will subscribe to these two topics. It will then use the messages published on both topics to provide a fused, locally accurate and smooth odometry information for Nav2.

## Robot Localization Demo


key: chroma:document
string_value:
## Robot Localization Demo

Therobot_localizationpackage is used to provide a fused and locally accurate smooth odometry information from the data provided byNodometry sensor inputs. These information can be provided to the package throughnav_msgs/Odometry,sensor_msgs/Imu,geometry_msgs/PoseWithCovarianceStamped, andgeometry_msgs/TwistWithCovarianceStampedmessages.

A usual robot setup consists of at least the wheel encoders and IMU as its odometry sensor sources. When multiple sources are provided torobot_localization, it is able to fuse the odometry information given by the sensors through the use of state estimation nodes. These nodes make use of either an Extended Kalman filter (ekf_node) or an Unscented Kalman Filter (ukf_node) to implement this fusion. In addition, the package also implements anavsat_transform_nodewhich transforms geographic coordinates into the robot’s world frame when working with GPS.


key: chroma:document
string_value:
Fused sensor data is published by therobot_localizationpackage through theodometry/filteredand theaccel/filteredtopics, if enabled in its configuration. In addition, it can also publish theodom=>base_linktransform on the/tftopic.

If your robot is only able to provide one odometry source, the use ofrobot_localizationwould have minimal effects aside from smoothing. In this case, an alternative approach is to publish transforms through a tf2 broadcaster in your single source of odometry node. Nevertheless, you can still opt to userobot_localizationto publish the transforms and some smoothing properties may still be observed in the output.

For the rest of this section, we will show how to userobot_localizationto fuse the sensors ofsam_bot. It will use thesensor_msgs/Imumessages published on/demo/Imuand thenav_msgs/Odometrymessage published on/demo/odomand then it will publish data onodometry/filtered,accel/filtered, and/tftopics.

## Configuring Robot Localization


key: chroma:document
string_value:
## Configuring Robot Localization

Let us now configure therobot_localizationpackage to use an Extended Kalman Filter (ekf_node) to fuse odometry information and publish theodom=>base_linktransform.

First, install therobot_localizationpackage using your machines package manager or by executing the following command:

Next, we specify the parameters of theekf_nodeusing a YAML file. Create a directory namedconfigat the root of your project and create a file namedekf.yaml. Copy the following lines of code into yourekf.yamlfile.

In this configuration, we defined the parameter values offrequency,two_d_mode,publish_acceleration,publish_tf,map_frame,odom_frame,base_link_frame, andworld_frame. For more information on the other parameters you can modify, seeParameters of state estimation nodes, and a sampleefk.yamlcan be foundhere.


key: chroma:document
string_value:
To add a sensor input to theekf_filter_node, add the next number in the sequence to its base name (odom, imu, pose, twist). In our case, we have onenav_msgs/Odometryand onesensor_msgs/Imuas inputs to the filter, thus we useodom0andimu0. We set the value ofodom0todemo/odom, which is the topic that publishes thenav_msgs/Odometry. Similarly, we set the value ofimu0to the topic that publishessensor_msgs/Imu, which isdemo/imu.

You can specify which values from a sensor are to be used by the filter using the_configparameter. The order of the values of this parameter is x, y, z, roll, pitch, yaw, vx, vy, vz, vroll, vpitch, vyaw, ax, ay, az. In our example, we set everything inodom0_configtofalseexcept the 1st, 2nd, 3rd, and 12th entries, which means the filter will only use the x, y, z, and the vyaw values ofodom0.


key: chroma:document
string_value:
In theimu0_configmatrix, you’ll notice that only roll, pitch, and yaw are used. Typical mobile robot-grade IMUs will also provide angular velocities and linear accelerations. Forrobot_localizationto work properly, you should not fuse in multiple fields that are derivative of each other. Since angular velocity is fused internally to the IMU to provide the roll, pitch and yaw estimates, we should not fuse in the angular velocities used to derive that information. We also do not fuse in angular velocity due to the noisy characteristics it has when not using exceptionally high quality (and expensive) IMUs.

## Launch and Build Files

Now, let us add theekf_nodeinto the launch file. Openlaunch/display.launch.pyand paste the following lines before thereturnlaunch.LaunchDescription([line.

Next, add the following launch arguments within thereturnlaunch.LaunchDescription([block.

Lastly, addrobot_localization_node,above therviz_nodeline to launch the robot localization node.


key: chroma:document
string_value:
Next, we need to add therobot_localizationdependency to our package definition. Openpackage.xmland add the following line below the last<exec_depend>tag.

Lastly, openCMakeLists.txtand append theconfigdirectory inside theinstall(DIRECTORY...), as shown in the snippet below.

## Build, Run and Verification

Let us now build and run our package. Navigate to the root of the project and execute the following lines:

Gazebo and RVIZ should launch. In the RVIZ window, you should see the model and TF frames ofsam_bot:

Next, let us verify that theodometry/filtered,accel/filtered, and/tftopics are active in the system. Open a new terminal and execute:

You should seeodometry/filtered,accel/filtered, and/tfin the list of the topics.

You can also check the subscriber count of these topics again by executing:

You should see that/demo/imuand/demo/odomnow both have 1 subscriber each.

To verify that theekf_filter_nodeare the subscribers of these topics, execute:

You should see an output as shown below.


key: chroma:document
string_value:
You should see an output as shown below.

From the output above, we can see that theekf_filter_nodeis subscribed to/demo/imuand/demo/odom. We can also see that theekf_filter_nodepublishes on theodometry/filtered,accel/filtered, and/tftopics.

You may also verify thatrobot_localizationis publishing theodom=>base_linktransform by using the tf2_echo utility. Run the following command in a separate command line terminal:

You should see a continuous output similar to what is shown below.

## Conclusion

In this guide, we have discussed the messages and transforms that are expected by Nav2 from the odometry system. We have seen how to set up an odometry system and how to verify the published messages. We also have discussed how multiple odometry sensors can be used to provide a filtered and smoothed odometry usingrobot_localization. We have also checked if theodom=>base_linktransform is being published correctly byrobot_localization.

Code Examples:

Language: unknown

File: nav_msgs/Odometry

```


key: chroma:document
string_value:
Language: unknown

File: nav_msgs/Odometry

```

# This represents estimates of position and velocity in free space.

# The pose in this message should be specified in the coordinate frame given by header.frame_id

# The twist in this message should be specified in the coordinate frame given by the child_frame_id

# Includes the frame id of the pose parent.

std_msgs/Header

header

# Frame id the pose is pointing at. The twist is in this coordinate frame.

string

child_frame_id

# Estimated pose that is typically relative to a fixed world frame.

geometry_msgs/PoseWithCovariance

pose

# Estimated linear and angular velocity relative to child_frame_id.

geometry_msgs/TwistWithCovariance

twist

```

Language: unknown

File: base_link

```

linear

=

(

right_wheel_est_vel

+

left_wheel_est_vel

)

/

2

angular

=

(

right_wheel_est_vel

left_wheel_est_vel

)

/

wheel_separation

;

```

Language: unknown

File: gazebo_ros_pkgs

```

sudo

apt

install

ros-<ros2-distro>-gazebo-ros-pkgs

```


key: chroma:document
string_value:
sudo

apt

install

ros-<ros2-distro>-gazebo-ros-pkgs

```

Language: unknown

File: </robot>

```

132

<link

name=

"imu_link"

>

133

<visual>

134

<geometry>

135

<box

size=

"0.1 0.1 0.1"

/>

136

</geometry>

137

</visual>

138

139

<collision>

140

<geometry>

141

<box

size=

"0.1 0.1 0.1"

/>

142

</geometry>

143

</collision>

144

145

<xacro:box_inertia

m=

"0.1"

w=

"0.1"

d=

"0.1"

h=

"0.1"

/>

146

</link>

147

148

<joint

name=

"imu_joint"

type=

"fixed"

>

149

<parent

link=

"base_link"

/>

150

<child

link=

"imu_link"

/>

151

<origin

xyz=

"0 0 0.01"

/>

152

</joint>

153

154

<gazebo

reference=

"imu_link"

>

155

<sensor

name=

"imu_sensor"

type=

"imu"

>

156

<plugin

filename=

"libgazebo_ros_imu_sensor.so"

name=

"imu_plugin"

>

157

<ros>

158

<namespace>

/demo

</namespace>

159

<remapping>

~/out:=imu

</remapping>

160

</ros>

161

<initial_orientation_as_reference>

false

</initial_orientation_as_reference>

162

</plugin>

163


key: chroma:document
string_value:
</initial_orientation_as_reference>

162

</plugin>

163

<always_on>

true

</always_on>

164

<update_rate>

100

</update_rate>

165

<visualize>

true

</visualize>

166

<imu>

167

<angular_velocity>

168

<x>

169

<noise

type=

"gaussian"

>

170

<mean>

0.0

</mean>

171

<stddev>

2e-4

</stddev>

172

<bias_mean>

0.0000075

</bias_mean>

173

<bias_stddev>

0.0000008

</bias_stddev>

174

</noise>

175

</x>

176

<y>

177

<noise

type=

"gaussian"

>

178

<mean>

0.0

</mean>

179

<stddev>

2e-4

</stddev>

180

<bias_mean>

0.0000075

</bias_mean>

181

<bias_stddev>

0.0000008

</bias_stddev>

182

</noise>

183

</y>

184

<z>

185

<noise

type=

"gaussian"

>

186

<mean>

0.0

</mean>

187

<stddev>

2e-4

</stddev>

188

<bias_mean>

0.0000075

</bias_mean>

189

<bias_stddev>

0.0000008

</bias_stddev>

190

</noise>

191

</z>

192

</angular_velocity>

193

<linear_acceleration>

194

<x>

195

<noise

type=

"gaussian"

>

196

<mean>

0.0

</mean>

197

<stddev>

1.7e-2


key: chroma:document
string_value:
>

196

<mean>

0.0

</mean>

197

<stddev>

1.7e-2

</stddev>

198

<bias_mean>

0.1

</bias_mean>

199

<bias_stddev>

0.001

</bias_stddev>

200

</noise>

201

</x>

202

<y>

203

<noise

type=

"gaussian"

>

204

<mean>

0.0

</mean>

205

<stddev>

1.7e-2

</stddev>

206

<bias_mean>

0.1

</bias_mean>

207

<bias_stddev>

0.001

</bias_stddev>

208

</noise>

209

</y>

210

<z>

211

<noise

type=

"gaussian"

>

212

<mean>

0.0

</mean>

213

<stddev>

1.7e-2

</stddev>

214

<bias_mean>

0.1

</bias_mean>

215

<bias_stddev>

0.001

</bias_stddev>

216

</noise>

217

</z>

218

</linear_acceleration>

219

</imu>

220

</sensor>

221

</gazebo>

```

Language: unknown

File: </gazebo>

```

223

<gazebo>

224

<plugin

name=

'diff_drive'

filename=

'libgazebo_ros_diff_drive.so'

>

225

<ros>

226

<namespace>

/demo

</namespace>

227

</ros>

228

229

<!-- wheels -->

230

<left_joint>

drivewhl_l_joint

</left_joint>

231

<right_joint>

drivewhl_r_joint

</right_joint>

232

233


key: chroma:document
string_value:
231

<right_joint>

drivewhl_r_joint

</right_joint>

232

233

<!-- kinematics -->

234

<wheel_separation>

0.4

</wheel_separation>

235

<wheel_diameter>

0.2

</wheel_diameter>

236

237

<!-- limits -->

238

<max_wheel_torque>

20

</max_wheel_torque>

239

<max_wheel_acceleration>

1.0

</max_wheel_acceleration>

240

241

<!-- output -->

242

<publish_odom>

true

</publish_odom>

243

<publish_odom_tf>

false

</publish_odom_tf>

244

<publish_wheel_tf>

true

</publish_wheel_tf>

245

246

<odometry_frame>

odom

</odometry_frame>

247

<robot_base_frame>

base_link

</robot_base_frame>

248

</plugin>

249

</gazebo>

```

Language: unknown

File: generate_launch_description()

```

joint_state_publisher_gui_node

=

launch_ros.actions.Node

(

package

=

'joint_state_publisher_gui'

,

executable

=

'joint_state_publisher_gui'

,

name

=

'joint_state_publisher_gui'

,

condition

=

launch.conditions.IfCondition

(

LaunchConfiguration

(

'gui'

))

)

```

Language: unknown


key: chroma:document
string_value:
LaunchConfiguration

(

'gui'

))

)

```

Language: unknown

File: generate_launch_description()

```

DeclareLaunchArgument

(

name

=

'gui'

,

default_value

=

'True'

,

description

=

'Flag to enable joint_state_publisher_gui'

)

```

Language: unknown

File: generate_launch_description()

```

joint_state_publisher_node

=

launch_ros.actions.Node

(

package

=

'joint_state_publisher'

,

executable

=

'joint_state_publisher'

,

name

=

'joint_state_publisher'

,

arguments

=[

default_model_path

]

,

#Add this line

parameters

=[{

'robot_description'

:

Command

([

'xarcro '

,

default_model_path

])}]

,

#Remove this line

condition

=

launch.conditions.UnlessCondition

(

LaunchConfiguration

(

'gui'

))

# Remove this line

)

```

Language: unknown

File: generate_launch_description()

```

<exec_depend>joint_state_publisher_gui</exec_depend>

```

Language: unknown

File: display.launch.py

```

launch.actions.ExecuteProcess

(

cmd

=[

'gazebo'

,

'--verbose'

,

'-s'

,


key: chroma:document
string_value:
(

cmd

=[

'gazebo'

,

'--verbose'

,

'-s'

,

'libgazebo_ros_init.so'

,

'-s'

,

'libgazebo_ros_factory.so'

]

,

output

=

'screen'

)

,

```

Language: unknown

File: returnlaunch.LaunchDescription([

```

spawn_entity

=

launch_ros.actions.Node

(

package

=

'gazebo_ros'

,

executable

=

'spawn_entity.py'

,

arguments

=[

'-entity'

,

'sam_bot'

,

'-topic'

,

'robot_description'

]

,

output

=

'screen'

)

```

Language: unknown

File: rviz_node

```

robot_state_publisher_node,

spawn_entity,

rviz_node

])

```

Language: unknown

File: /demo/odom

```

colcon

build

.

install/setup.bash

ros2

launch

sam_bot_description

display.launch.py

```

Language: unknown

File: sam_bot

```

ros2

topic

list

```

Language: unknown

File: /demo/odom

```

ros2

topic

info

/demo/imu

ros2

topic

info

/demo/odom

```

Language: unknown

File: /demo/odom

```

Type:

sensor_msgs/msg/Imu

Publisher

count:

1

Subscription

count:

0

```

Language: unknown

File: /demo/odom

```


key: chroma:document
string_value:
count:

0

```

Language: unknown

File: /demo/odom

```

Type:

nav_msgs/msg/Odometry

Publisher

count:

1

Subscription

count:

0

```

Language: unknown

File: robot_localization

```

sudo

apt

install

ros-<ros2-distro>-robot-localization

```

Language: unknown

File: ekf.yaml

```

### ekf config file ###

ekf_filter_node

:

ros__parameters

:

# The frequency, in Hz, at which the filter will output a position estimate. Note that the filter will not begin

# computation until it receives at least one message from one of theinputs. It will then run continuously at the

# frequency specified here, regardless of whether it receives more measurements. Defaults to 30 if unspecified.

frequency

:

30.0

# ekf_localization_node and ukf_localization_node both use a 3D omnidirectional motion model. If this parameter is

# set to true, no 3D information will be used in your state estimate. Use this if you are operating in a planar


key: chroma:document
string_value:
# environment and want to ignore the effect of small variations in the ground plane that might otherwise be detected

# by, for example, an IMU. Defaults to false if unspecified.

two_d_mode

:

false

# Whether to publish the acceleration state. Defaults to false if unspecified.

publish_acceleration

:

true

# Whether to broadcast the transformation over the /tf topic. Defaultsto true if unspecified.

publish_tf

:

true

# 1. Set the map_frame, odom_frame, and base_link frames to the appropriate frame names for your system.

#     1a. If your system does not have a map_frame, just remove it, and make sure "world_frame" is set to the value of odom_frame.

# 2. If you are fusing continuous position data such as wheel encoder odometry, visual odometry, or IMU data, set "world_frame"

#    to your odom_frame value. This is the default behavior for robot_localization's state estimation nodes.


key: chroma:document
string_value:
# 3. If you are fusing global absolute position data that is subject to discrete jumps (e.g., GPS or position updates from landmark

#    observations) then:

#     3a. Set your "world_frame" to your map_frame value

#     3b. MAKE SURE something else is generating the odom->base_link transform. Note that this can even be another state estimation node

#         from robot_localization! However, that instance should *not* fuse the global data.

map_frame

:

map

# Defaults to "map" if unspecified

odom_frame

:

odom

# Defaults to "odom" if unspecified

base_link_frame

:

base_link

# Defaults to "base_link" ifunspecified

world_frame

:

odom

# Defaults to the value ofodom_frame if unspecified

odom0

:

demo/odom

odom0_config

:

[

true

,

true

,

true

,

false

,

false

,

false

,

false

,

false

,

false

,

false

,

false

,

true

,

false

,

false

,

false

]

imu0

:

demo/imu

imu0_config

:

[

false

,

false

,

false

,

true

,

true

,

true

,

false

,

false

,

false

,


key: chroma:document
string_value:
,

true

,

true

,

true

,

false

,

false

,

false

,

false

,

false

,

false

,

false

,

false

,

false

]

```

Language: unknown

File: returnlaunch.LaunchDescription([

```

robot_localization_node

=

launch_ros.actions.Node

(

package

=

'robot_localization'

,

executable

=

'ekf_node'

,

name

=

'ekf_filter_node'

,

output

=

'screen'

,

parameters

=[

os.path.join

(

pkg_share,

'config/ekf.yaml'

)

,

{

'use_sim_time'

:

LaunchConfiguration

(

'use_sim_time'

)}]

)

```

Language: unknown

File: returnlaunch.LaunchDescription([

```

launch.actions.DeclareLaunchArgument

(

name

=

'use_sim_time'

,

default_value

=

'True'

,

description

=

'Flag to enable use_sim_time'

)

,

```

Language: unknown

File: rviz_node

```

robot_state_publisher_node,

spawn_entity,

robot_localization_node,

rviz_node

])

```

Language: unknown

File: <exec_depend>

```

<exec_depend>robot_localization</exec_depend>

```

Language: unknown

File: install(DIRECTORY...)

```

install


key: chroma:document
string_value:
Language: unknown

File: install(DIRECTORY...)

```

install

(

DIRECTORY

src

launch

rviz

config

DESTINATION

share/

${

PROJECT_NAME

}

)

```

Language: unknown

File: install(DIRECTORY...)

```

colcon

build

.

install/setup.bash

ros2

launch

sam_bot_description

display.launch.py

```

Language: unknown

File: /tf

```

ros2

topic

list

```

Language: unknown

File: /tf

```

ros2

topic

info

/demo/imu

ros2

topic

info

/demo/odom

```

Language: unknown

File: ekf_filter_node

```

ros2

node

info

/ekf_filter_node

```

Language: unknown

File: ekf_filter_node

```

/ekf_filter_node

Subscribers:

/demo/imu:

sensor_msgs/msg/Imu

/demo/odom:

nav_msgs/msg/Odometry

/parameter_events:

rcl_interfaces/msg/ParameterEvent

/set_pose:

geometry_msgs/msg/PoseWithCovarianceStamped

Publishers:

/accel/filtered:

geometry_msgs/msg/AccelWithCovarianceStamped

/diagnostics:

diagnostic_msgs/msg/DiagnosticArray

/odometry/filtered:

nav_msgs/msg/Odometry

/parameter_events:


key: chroma:document
string_value:
/odometry/filtered:

nav_msgs/msg/Odometry

/parameter_events:

rcl_interfaces/msg/ParameterEvent

/rosout:

rcl_interfaces/msg/Log

/tf:

tf2_msgs/msg/TFMessage

Service

Servers:

...

```

Language: unknown

File: base_link

```

ros2

run

tf2_ros

tf2_echo

odom

base_link

```

Language: unknown

File: base_link

```

At

time

8

.842000000

Translation:

[

0

.003,

0.000,

0

.127

]

Rotation:

in

Quaternion

[

0.000,

0

.092,

0

.003,

0

.996

]

At

time

9

.842000000

Translation:

[

0

.002,

0.000,

0

.127

]

Rotation:

in

Quaternion

[

0.000,

0

.092,

0

.003,

0

.996

]

```


key: chroma:document
string_value:
Title: Build and Install

URL: https://docs.nav2.org/development_guides/build_docs/index.html#generate

doxygen

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Install Nav2 and its dependencies are released as binaries. You may install it via the following to get the latest stable released version:

## For Iron and Older

## For Jazzy and Newer

## Build There are a few ways to build Nav2 using:

## Released Distribution Binaries To build Nav2, you’ll first need to build or install ROS 2 and related development tools, including:colcon,rosdepandvcstool. Once your environment is setup, clone the repo, install all dependencies, and build the workspace: You can thensource~/nav2_ws/install/setup.bashto get ready for demonstrations!


key: chroma:document
string_value:
## Rolling Development Source Building Nav2 using rolling development source is similar to building Nav2 from released distribution binaries, where instead you build dependencies from source using the main development branches for all ROS based packages. Nav2 does not currently release binaries on rolling, so it must be build from source. Once your environment is setup, clone the repo and build the workspace: You can thensource~/nav2_ws/install/setup.bashto get ready for demonstrations! It is safe to ignore the rosdep error of from the missingslam_toolboxkey.


key: chroma:document
string_value:
## Docker Container Images Building Nav2 using Docker container images provides a repeatable and reproducible environment to automate and self document the entire setup process. Instead of manually invoking the development tools as documented above, you can leverage the project’s Dockerfiles to build and install Nav2 for various distributions. Once your system is setup, you can build the Nav2 Dockerfile from the root of the repo: Thedocker buildcommand above creates a tagged image using theDockerfilefrom the context specified using the path to the repo, where build-time variables are set using additional arguments, e.g. passing a set ofcolcon mixinsto configure the workspace build. Check theARGdirectives in theDockerfileto discover all build-time variables available. The command also specifies anexternal cache sourceto pull the latest cached image from Nav2’sContainer Registryto speed up the build process.


key: chroma:document
string_value:
## Generate Doxygen Rundoxygenin the root of the Nav2 repository. It will generate a/doc/*directory containing the documentation. The documentation entrypoint in a browser is index.html.

## Help

Build Troubleshooting Guide

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

source

/opt/ros/<distro>/setup.bash

sudo

apt

install

\

ros

$ROS_DISTRO

navigation2

\

ros

$ROS_DISTRO

nav2

bringup

\

ros

$ROS_DISTRO

turtlebot3*

```

Language: unknown

File: use_cancel_deceleration

```

source

/opt/ros/<distro>/setup.bash

sudo

apt

install

\

ros

$ROS_DISTRO

navigation2

\

ros

$ROS_DISTRO

nav2

bringup

\

ros

$ROS_DISTRO

nav2

minimal

tb*

```

Language: unknown

File: main

```

source

/opt/ros/<distro>/setup.bash

mkdir

p

~/nav2_ws/src

&&

cd

~/nav2_ws

git

clone

https://github.com/ros

navigation/navigation2.git

branch

$ROS_DISTRO

./src/navigation2

rosdep

install

y

\

from

paths

./src

\

ignore

src

colcon

build

\

symlink

install

```


key: chroma:document
string_value:
./src

\

ignore

src

colcon

build

\

symlink

install

```

Language: unknown

File: source~/nav2_ws/install/setup.bash

```

source

<ros_ws>/install/setup.bash

mkdir

p

~/nav2_ws/src

&&

cd

~/nav2_ws

git

clone

https://github.com/ros

navigation/navigation2.git

branch

main

./src/navigation2

git

clone

https://github.com/ros

navigation/nav2_minimal_turtlebot_simulation.git

branch

main

./src/nav2_minimal_turtlebot_simulation

rosdep

install

r

y

\

from

paths

./src

\

ignore

src

colcon

build

\

symlink

install

```

Language: unknown

File: slam_toolbox

```

export

ROS_DISTRO

=

rolling

git

clone

https://github.com/ros

navigation/navigation2.git

branch

main

docker

build

tag

navigation2:

$ROS_DISTRO

\

build

arg

FROM_IMAGE

=

ros:

$ROS_DISTRO

\

build

arg

OVERLAY_MIXINS

=

"release ccache lld"

\

cache

from

ghcr.io/ros

navigation/navigation2:main

\

./navigation2

```


key: chroma:document
string_value:
Title: Getting Involved

URL: https://docs.nav2.org/development_guides/involvement_docs/index.html

Section: getting_started/index.html

--------------------------------------------------------------------------------


key: chroma:document
string_value:
## Getting Involved If you’re interested in getting involved in Navigation 2, first of all, welcome! We encourage everyone to get involved from students, to junior developers, to senior developers, and executives. There’s something to do for everyone from bug fixes, to feature development, new algorithms, and refactoring. All ROS 2 TSC Working Groups have their meetings on theworking group calendar. Here, you can find the date and time of the Navigation2 working group meeting. Make sure you’re checking in your local timezone. From this calendar, you can add yourself to the event so it will appear on your google calendar and get the event link to the call through Google Hangouts. We encourage everyone interested to come to the meeting to introduce yourself, your project, and see what everyone is working on. Further,ROS Discourseis a good place to follow larger discussions happening in the community and announcements. This isnotthe correct place to post questions or ask for assistance. Please visitROS


key: chroma:document
string_value:
place to post questions or ask for assistance. Please visitROS Answersfor Q&A. Lastly, we have aCommunity Slackwhere we chat in real-time about topics in public channels or sidebar maintainers on individual projects via PMs. If you’re interested in contributing to Nav2, this is a great place to join! If you’re looking to contribute code or bugs, please see the Process section below. Over time, for developers that have an interest and have shown technical competence in an area of the stack, we elevate developers to a maintainers status. That allows push rights to our protected branches, first-reviewers rights, and getting your name onAbout and Contact. There currently is not a clear process for getting to be a maintainer, but if you’ve been involved and contributing over a duration of several months, you may be a good candidate and should email the project lead listed onAbout and Contact.


key: chroma:document
string_value:
## Process After you’ve introduced yourself in a working group meeting (recommended, not required), you’re ready to get started! We recommend a typical open-source project flow and value detail and transparency. If you commit to something and need to pull back, say so. We all know priorities change and appreciate the heads up so that task can go into the open queue of tasks. The process is simple and is as follow: Note: We take code quality seriously and strive for high-quality and consistent code. We make use of the linting and static analysis tools provided in ROS 2 (ament_cpplint,ament_uncrustify,ament_cppcheck, etc). All PRs are built in CI with the appropriate ROS distributions and run through a set of unit and system level tests including static analysis. You can see the results of these tests in the pull request. It is expected for feature development for tests to cover this work to be added. If any documentation must be updated due to your changes, that should be included in your pull request.


key: chroma:document
string_value:
## Licensing Licensing is very important to open source projects. It helps ensure the software continues to be available under the terms that the author desired. Because much of the source code is ported from other ROS 1 projects, each package has it’s own license. Contributions should be made under the predominant license of that package. Entirely new packages should be made available under theApache 2.0 license. A license tells you what rights you have as a developer, as provided by the copyright holder. It is important that the contributor fully understands the licensing rights and agrees to them. Sometimes the copyright holder isn’t the contributor, such as when the contributor is doing work on behalf of a company. If for some reason Apache 2.0 or BSD licenses are not appropriate for your work, please get in contact with a project maintainer and discuss your concerns or requirements. We may consider special exceptions for exceptional work, within reason (we will not accept any licenses that makes it


key: chroma:document
string_value:
## Developer Certification of Origin (DCO) To make a good faith effort to ensure licensing criteria are met, Nav2 encourages the Developer Certificate of Origin (DCO) process to be followed. The DCO is an attestation attached to every contribution made by a developer. In the commit message of the contribution, (described more fully later in this document), the developer simply adds aSigned-off-bystatement and thereby agrees to the DCO. In practice, its easier to justgitcommit-s-m"commitmessage.". Where-sadds this automatically. If you forgot to add this to a commit, it is easy to append via:gitcommit--amend-s. When a developer submits a patch, it is a commitment that the contributor has the right to submit the patch per the license.  The DCO agreement is shown below and athttp://developercertificate.org/.

Code Examples:

Language: unknown File: gitcommit--amend-s ``` Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:


key: chroma:document
string_value:
By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or

(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as Indicated in the file; or

(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.


key: chroma:document
string_value:
(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.

```


key: chroma:document
string_value:
Title: Collision Monitor Node

URL: https://docs.nav2.org/configuration/packages/collision_monitor/configuring-collision-monitor-node.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Features

The Collision Monitor uses polygons relative the robot’s base frame origin to define “zones”.

Data that fall into these zones trigger an operation depending on the model being used.

A given instance of the Collision Monitor can have many zones with different models at the same time.

When multiple zones trigger at once, the most aggressive one is used (e.g. stop > slow 50% > slow 10%).

The following models of safety behaviors are employed by Collision Monitor:

The zones around the robot can take the following shapes:

All shapes (Polygon,CircleandVelocityPolygon) are derived from basePolygonclass, so without loss of generality they would be called as “polygons”.


key: chroma:document
string_value:
Subscribed footprint is also having the same properties as other polygons, but it is being obtained a footprint topic for the Approach Model.

The data may be obtained from different data sources:

## Parameters

## Polygons parameters

<polygonname>is the corresponding polygon name ID selected for this type.

## VelocityPolygon parameters

All previous Polygon parameters apply, in addition to the following unique parameters for VelocityPolygon.

## Observation sources parameters

<sourcename>is the corresponding data source name ID selected for this type.

## Example

Here is an example illustrating the common configurations for holonomic robots that cover multiple directions of the resultant velocity:

Here is an example of configuration YAML for the Collision Monitor.

Code Examples:

Language: unknown

File: source_timeout:0.0

```

collision_monitor

:

ros__parameters

:

base_frame_id

:

"base_footprint"

odom_frame_id

:

"odom"

cmd_vel_in_topic

:

"cmd_vel_smoothed"

cmd_vel_out_topic

:


key: chroma:document
string_value:
cmd_vel_in_topic

:

"cmd_vel_smoothed"

cmd_vel_out_topic

:

"cmd_vel"

state_topic

:

"collision_monitor_state"

transform_tolerance

:

0.5

source_timeout

:

5.0

base_shift_correction

:

True

stop_pub_timeout

:

2.0

enable_stamped_cmd_vel

:

True

# False for Jazzy or older

use_realtime_priority

:

false

polygons

:

[

"PolygonStop"

,

"PolygonSlow"

,

"FootprintApproach"

]

PolygonStop

:

type

:

"circle"

radius

:

0.3

action_type

:

"stop"

min_points

:

4

# max_points: 3 for Humble

visualize

:

True

polygon_pub_topic

:

"polygon_stop"

enabled

:

True

PolygonSlow

:

type

:

"polygon"

points

:

"[[1.0,

1.0],

[1.0,

1.0],

[-0.5,

1.0],

[-0.5,

1.0]]"

action_type

:

"slowdown"

min_points

:

4

# max_points: 3 for Humble

slowdown_ratio

:

0.3

visualize

:

True

polygon_pub_topic

:

"polygon_slowdown"

enabled

:

True

PolygonLimit

:

type

:

"polygon"

points

:

"[[0.5,

0.5],

[0.5,

0.5],

[-0.5,

0.5],

[-0.5,

0.5]]"

action_type

:

"limit"


key: chroma:document
string_value:
0.5],

[-0.5,

0.5],

[-0.5,

0.5]]"

action_type

:

"limit"

min_points

:

4

# max_points: 3 for Humble

linear_limit

:

0.4

angular_limit

:

0.5

visualize

:

True

polygon_pub_topic

:

"polygon_limit"

enabled

:

True

FootprintApproach

:

type

:

"polygon"

action_type

:

"approach"

footprint_topic

:

"/local_costmap/published_footprint"

time_before_collision

:

2.0

simulation_time_step

:

0.02

min_points

:

6

# max_points: 5 for Humble

visualize

:

False

enabled

:

True

VelocityPolygonStop

:

type

:

"velocity_polygon"

action_type

:

"stop"

min_points

:

6

visualize

:

True

enabled

:

True

polygon_pub_topic

:

"velocity_polygon_stop"

velocity_polygons

:

[

"rotation"

,

"translation_forward"

,

"translation_backward"

,

"stopped"

]

holonomic

:

false

rotation

:

points

:

"[[0.3,

0.3],

[0.3,

0.3],

[-0.3,

0.3],

[-0.3,

0.3]]"

linear_min

:

0.0

linear_max

:

0.05

theta_min

:

1.0

theta_max

:

1.0

translation_forward

:

points

:

"[[0.35,


key: chroma:document
string_value:
theta_max

:

1.0

translation_forward

:

points

:

"[[0.35,

0.3],

[0.35,

0.3],

[-0.2,

0.3],

[-0.2,

0.3]]"

linear_min

:

0.0

linear_max

:

1.0

theta_min

:

1.0

theta_max

:

1.0

translation_backward

:

points

:

"[[0.2,

0.3],

[0.2,

0.3],

[-0.35,

0.3],

[-0.35,

0.3]]"

linear_min

:

1.0

linear_max

:

0.0

theta_min

:

1.0

theta_max

:

1.0

# This is the last polygon to be checked, it should cover the entire range of robot's velocities

# It is used as the stopped polygon when the robot is not moving and as a fallback if the velocity

# is not covered by any of the other sub-polygons

stopped

:

points

:

"[[0.25,

0.25],

[0.25,

0.25],

[-0.25,

0.25],

[-0.25,

0.25]]"

linear_min

:

1.0

linear_max

:

1.0

theta_min

:

1.0

theta_max

:

1.0

observation_sources

:

[

"scan"

,

"pointcloud"

]

scan

:

source_timeout

:

0.2

type

:

"scan"

topic

:

"/scan"

enabled

:

True

pointcloud

:

type

:

"pointcloud"

topic

:

"/intel_realsense_r200_depth/points"


key: chroma:document
string_value:
"pointcloud"

topic

:

"/intel_realsense_r200_depth/points"

min_height

:

0.1

max_height

:

0.5

enabled

:

True

```


key: chroma:document
string_value:
Title: Speed Filter Parameters

URL: https://docs.nav2.org/configuration/packages/costmap

plugins/speed_filter.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: <filtername>

```

global_costmap

:

global_costmap

:

ros__parameters

:

...

plugins

:

[

"static_layer"

,

"obstacle_layer"

,

"inflation_layer"

]

filters

:

[

"speed_filter"

]

...

speed_filter

:

plugin

:

"nav2_costmap_2d::SpeedFilter"

enabled

:

True

filter_info_topic

:

"/costmap_filter_info"

speed_limit_topic

:

"/speed_limit"

transform_tolerance

:

0.1

```


key: chroma:document
string_value:
Title: UndockRobot

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/UndockRobot.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Output Ports

## Example

Code Examples:

Language: unknown

File: UndockRobot

```

<UndockRobot

dock_type=

"{dock_type}"

/>

```


key: chroma:document
string_value:
Title: IsBatteryLow

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/IsBatteryLow.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: is_voltage

```

<IsBatteryLow

min_battery=

"0.5"

battery_topic=

"/battery_status"

is_voltage=

"false"

/>

```


key: chroma:document
string_value:
Title: GoalCheckerSelector

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/GoalCheckerSelector.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Output Ports

## Example

Code Examples:

Language: unknown

File: transientlocal

```

<GoalCheckerSelector

selected_goal_checker=

"{selected_goal_checker}"

default_goal_checker=

"precise_goal_checker"

topic_name=

"goal_checker_selector"

/>

```


key: chroma:document
string_value:
Title: Behavior Tree XML Nodes

URL: https://docs.nav2.org/configuration/packages/configuring-bt-xml.html#decorator-plugins

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Action Plugins

## Condition Plugins

## Control Plugins

## Decorator Plugins

## Example

This Behavior Tree replans the global path periodically at 1 Hz and it also has

recovery actions.

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<root

main_tree_to_execute=

"MainTree"

>

<BehaviorTree

ID=

"MainTree"

>

<RecoveryNode

number_of_retries=

"6"

name=

"NavigateRecovery"

>

<PipelineSequence

name=

"NavigateWithReplanning"

>

<RateController

hz=

"1.0"

>

<RecoveryNode

number_of_retries=

"1"

name=

"ComputePathToPose"

>

<ComputePathToPose

goal=

"{goal}"

path=

"{path}"

planner_id=

"GridBased"

/>

<ReactiveFallback

name=

"ComputePathToPoseRecoveryFallback"

>

<GoalUpdated/>

<ClearEntireCostmap

name=


key: chroma:document
string_value:
>

<GoalUpdated/>

<ClearEntireCostmap

name=

"ClearGlobalCostmap-Context"

service_name=

"global_costmap/clear_entirely_global_costmap"

/>

</ReactiveFallback>

</RecoveryNode>

</RateController>

<RecoveryNode

number_of_retries=

"1"

name=

"FollowPath"

>

<FollowPath

path=

"{path}"

controller_id=

"FollowPath"

/>

<ReactiveFallback

name=

"FollowPathRecoveryFallback"

>

<GoalUpdated/>

<ClearEntireCostmap

name=

"ClearLocalCostmap-Context"

service_name=

"local_costmap/clear_entirely_local_costmap"

/>

</ReactiveFallback>

</RecoveryNode>

</PipelineSequence>

<ReactiveFallback

name=

"RecoveryFallback"

>

<GoalUpdated/>

<RoundRobin

name=

"RecoveryActions"

>

<Sequence

name=

"ClearingActions"

>

<ClearEntireCostmap

name=

"ClearLocalCostmap-Subtree"

service_name=

"local_costmap/clear_entirely_local_costmap"

/>

<ClearEntireCostmap

name=

"ClearGlobalCostmap-Subtree"

service_name=

"global_costmap/clear_entirely_global_costmap"

/>

</Sequence>

<Spin

spin_dist=

"1.57"

/>


key: chroma:document
string_value:
/>

</Sequence>

<Spin

spin_dist=

"1.57"

/>

<Wait

wait_duration=

"5"

/>

<BackUp

backup_dist=

"0.15"

backup_speed=

"0.025"

/>

</RoundRobin>

</ReactiveFallback>

</RecoveryNode>

</BehaviorTree>

</root>

```


key: chroma:document
string_value:
Title: CancelDriveOnHeading

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/CancelDriveOnHeading.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: drive_on_heading

```

<CancelDriveOnHeading

server_name=

"drive_on_heading"

server_timeout=

"10"

/>

```


key: chroma:document
string_value:
Title: Getting Started

URL: https://docs.nav2.org/getting_started/index.html

Section: development_guides/index.html

--------------------------------------------------------------------------------

## Installation Jazzy introduced the new Gazebo modern simulator, replacing Gazebo Classic. Thus, for Jazzy and newer, the installation packages and instructions are slightly different to pull in the appropriate packages. ForJazzy and newer, install the Turtlebot 3 & 4 packages for Gazebo Modern. It should be automatically installed withnav2_bringup: ForIron and older, install Turtlebot 3 packages for gazebo classic:

## Running the Example


key: chroma:document
string_value:
## Navigating After starting, the robot initially has no idea where it is. By default, Nav2 waits for you to give it an approximate starting position. Take a look at where the robot is in the Gazebo world, and find that spot on the map. Set the initial pose by clicking the “2D Pose Estimate” button in RViz, and then down clicking on the map in that location. You set the orientation by dragging forward from the down click. If you are using the defaults so far, the robot should look roughly like this. If you don’t get the location exactly right, that’s fine. Nav2 will refine the position as it navigates. You can also, click the “2D Pose Estimate” button and try again, if you prefer. Once you’ve set the initial pose, the transform tree will be complete and Nav2 will be fully active and ready to go. You should see the robot and particle cloud now. Next, click the “Navigaton2 Goal” button and choose a destination. This will call the BT navigator to go to that goal through an action server. You can pause (cancel)


key: chroma:document
string_value:
to that goal through an action server. You can pause (cancel) or reset the action through the Nav2 rviz plugin shown. Now watch the robot go!


key: chroma:document
string_value:
Code Examples:

Language: unknown

File: use_cancel_deceleration

```

sudo

apt

install

ros

<ros2

distro>

navigation2

sudo

apt

install

ros

<ros2

distro>

nav2

bringup

```

Language: unknown

File: nav2_bringup

```

sudo

apt

install

ros

<ros2

distro>

nav2

minimal

tb*

```

Language: unknown

File: nav2_bringup

```

sudo

apt

install

ros

<ros2

distro>

turtlebot3

gazebo

```

Language: unknown

File: nav2_bringup

```

source

/opt/ros/<ros2

distro>/setup.bash

export TURTLEBOT3_MODEL = waffle # Iron and older only with Gazebo Classic export GAZEBO_MODEL_PATH = $GAZEBO_MODEL_PATH :/opt/ros/<ros2-distro>/share/turtlebot3_gazebo/models # Iron and older only with Gazebo Classic ```

Language: unknown

File: nav2_bringup

```

ros2

launch

nav2_bringup

tb3_simulation_launch.py

headless:

=

False

```


key: chroma:document
string_value:
Title: Navigation Concepts

URL: https://docs.nav2.org/concepts/index.html

Section: concepts/index.html

--------------------------------------------------------------------------------

## ROS 2 ROS 2 is the core middleware used for Nav2. If you are unfamiliar with this, please visitthe ROS 2 documentationbefore continuing.


key: chroma:document
string_value:
## Action Server Just as in ROS, action servers are a common way to control long running tasks like navigation. This stack makes more extensive use of actions, and in some cases, without an easy topic interface. It is more important to understand action servers as a developer in ROS 2. Some simple CLI examples can be found in theROS 2 documentation. Action servers are similar to a canonical service server. A client will request some task to be completed, except, this task may take a long time. An example would be moving the shovel up from a bulldozer or ask a robot to travel 10 meters to the right. In this situation, action servers and clients allow us to call a long-running task in another process or thread and return a future to its result. It is permissible at this point to block until the action is complete, however, you may want to occasionally check if the action is complete and continue to process work in the client thread. Since it is long-running, action servers will also provide feedback to their


key: chroma:document
string_value:
action servers will also provide feedback to their clients. This feedback can be anything and is defined in the ROS.actionalong with the request and result types. In the bulldozer example, a request may be an angle, a feedback may be the angle remaining to be moved, and the result is a success or fail boolean with the end angle. In the navigation example, a request may be a position, a feedback may be the time its been navigating for and the distance to the goal, and the result a boolean for success. Feedback and results can be gathered synchronously by registering callbacks with the action client. They may also be gathered by asynchronously requesting information from the shared future objects. Both require spinning the client node to process callback groups. Action servers are used in this stack to communicate with the highest level Behavior Tree (BT) navigator through aNavigateToPoseaction message. They are also used for the BT navigator to communicate with the subsequent smaller action servers to compute


key: chroma:document
string_value:
with the subsequent smaller action servers to compute plans, control efforts, and recoveries. Each will have their own unique.actiontype innav2_msgsfor interacting with the servers.


key: chroma:document
string_value:
## Lifecycle Nodes and Bond Lifecycle (or Managed, more correctly) nodes are unique to ROS 2. More information can befound here. They are nodes that contain state machine transitions for bringup and teardown of ROS 2 servers. This helps in deterministic behavior of ROS systems in startup and shutdown. It also helps users structure their programs in reasonable ways for commercial uses and debugging. When a node is started, it is in the unconfigured state, only processing the node’s constructor which shouldnotcontain any ROS networking setup or parameter reading. By the launch system, or the supplied lifecycle manager, the nodes need to be transitioned to inactive by configuring. After, it is possible to activate the node by transitioning through the activating stage. This state will allow the node to process information and be fully setup to run. The configuration stage, triggering theon_configure()method, will setup all parameters, ROS networking interfaces, and for safety systems, all dynamically allocated


key: chroma:document
string_value:
interfaces, and for safety systems, all dynamically allocated memory. The activation stage, triggering theon_activate()method, will active the ROS networking interfaces and set any states in the program to start processing information. To shutdown, we transition into deactivating, cleaning up, shutting down and end in the finalized state. The networking interfaces are deactivated and stop processing, deallocate memory, exit cleanly, in those stages, respectively. The lifecycle node framework is used extensively through out this project and all servers utilize it. It is best convention for all ROS systems to use lifecycle nodes if it is possible. Within Nav2, we use a wrapper of LifecycleNodes,nav2_utilLifecycleNode. This wrapper wraps much of the complexities of LifecycleNodes for typical applications. It also includes abondconnection for the lifecycle manager to ensure that after a server transitions up, it also remains active. If a server crashes, it lets the lifecycle manager know and transition down the


key: chroma:document
string_value:
it lets the lifecycle manager know and transition down the system to prevent a critical failure. SeeEloquent to Foxyfor details.


key: chroma:document
string_value:
## Behavior Trees Behavior trees (BT) are becoming increasingly common in complex robotics tasks. They are a tree structure of tasks to be completed. It creates a more scalable and human-understandable framework for defining multi-step or many state applications. This is opposed to a finite state machine (FSM) which may have dozens of states and hundreds of transitions. An example would be a soccer-playing robot. Embedding the logic of soccer game play into a FSM would be challenging and error prone with many possible states and rules. Additionally, modeling choices like to shoot at the goal from the left, right, or center, is particularly unclear. With a BT, basic primitives, like “kick”, “walk”, “go to ball”, can be created and reused for many behaviors. More information can be foundin this book. Istronglyrecommend reading chapters 1-3 to get a good understanding of the nomenclature and workflow. It should only take about 30 minutes. Behavior Trees provide a formal structure for navigation logic which can


key: chroma:document
string_value:
Trees provide a formal structure for navigation logic which can be both used to create complex systems but also be verifiable and validated as provenly correct using advanced tools. Having the application logic centralized in the behavior tree and with independent task servers (which only communicate data over the tree) allows for formal analysis. For this project, we useBehaviorTree CPP V4as the behavior tree library. We create node plugins which can be constructed into a tree, inside theBTNavigator. The node plugins are loaded into the BT and when the XML file of the tree is parsed, the registered names are associated. At this point, we can march through the behavior tree to navigate. One reason this library is used is its ability to load subtrees. This means that the Nav2 behavior tree can be loaded into another higher-level BT to use this project as node plugin. An example would be in soccer play, using the Nav2 behavior tree as the “go to ball” node with a ball detection as part of a larger task.


key: chroma:document
string_value:
to ball” node with a ball detection as part of a larger task. Additionally, we supply aNavigateToPoseActionplugin (among others) for BT so the Nav2 stack can be called from a client application through the usual action interface. Other systems could be used to design complex autonomous behavior, namely Hierarchical FSMs (HFSM). Behavior Trees were selected due to popularity across the robotics and related industries and by largely user demand. However, due to the independent task server nature of Nav2, it is not difficult to offer anav2_hfsm_navigatorpackage in the future, pending interest and contribution.


key: chroma:document
string_value:
## Navigation Servers Planners and controllers are at the heart of a navigation task. Recoveries are used to get the robot out of a bad situation or attempt to deal with various forms of issues to make the system fault-tolerant. Smoothers can be used for additional quality improvements of the planned path. In this section, the general concepts around them and their uses in this project are analyzed.


key: chroma:document
string_value:
## Planner, Controller, Smoother and Recovery Servers Four of the action servers in this project are the planner, behavior, smoother and controller servers. These action servers are used to host a map of algorithm plugins to complete various tasks. They also host the environmental representation used by the algorithm plugins to compute their outputs. The planner, smoother and controller servers will be configured at runtime with the names (aliases) and types of algorithms to use. These types are the pluginlib names that have been registered and the names are the aliases for the task. An example would be the DWB controller used with nameFollowPath, as it follows a reference path. In this case, then all parameters for DWB would be placed in that namespace, e.g.FollowPath.<param>. These three servers then expose an action interface corresponding to their task. When the behavior tree ticks the corresponding BT node, it will call the action server to process its task. The action server callback inside the server


key: chroma:document
string_value:
process its task. The action server callback inside the server will call the chosen algorithm by its name (e.g.FollowPath) that maps to a specific algorithm. This allows a user to abstract the algorithm used in the behavior tree to classes of algorithms. For instance, you can haveNplugin controllers to follow paths, dock with charger, avoid dynamic obstacles, or interface with a tool. Having all of these plugins in the same server allows the user to make use of a single environmental representation object, which is costly to duplicate. For the behavior server, each of the behaviors also contains their own name, however, each plugin will also expose its own special action server. This is done because of the wide variety of behavior actions that may be created which cannot have a single simple interface to share. The behavior server also contains a costmap subscriber to the local costmap, receiving real-time updates from the controller server, to compute its tasks. We do this to avoid having multiple instances


key: chroma:document
string_value:
its tasks. We do this to avoid having multiple instances of the local costmap which are computationally expensive to duplicate. Alternatively, since the BT nodes are trivial plugins calling an action, new BT nodes can be created to call other action servers with other action types. It is advisable to use the provided servers if possible at all times. If, due to the plugin or action interfaces, a new server is needed, that can be sustained with the framework. The new server should use the new type and plugin interface, similar to the provided servers. A new BT node plugin will need to be created to call the new action server – however no forking or modification is required in the Nav2 repo itself by making extensive use of servers and plugins. If you find that you require a new interface to the pluginlib definition or action type, please file a ticket and see if we can rectify that in the same interfaces.


key: chroma:document
string_value:
## Planners The task of a planner is to compute a path to complete some objective function. The path can also be known as a route, depending on the nomenclature and algorithm selected. Two canonical examples are computing a plan to a goal (e.g. from current position to a goal) or complete coverage (e.g. plan to cover all free space). The planner will have access to a global environmental representation and sensor data buffered into it. Planners can be written to: The general task in Nav2 for the planner is to compute a valid, and potentially optimal, path from the current pose to a goal pose. However, many classes of plans and routes exist which are supported.


key: chroma:document
string_value:
## Controllers Controllers, also known as local planners in ROS 1, are the way we follow the globally computed path or complete a local task. The controller will have access to a local environment representation to attempt to compute feasible control efforts for the base to follow. Many controller will project the robot forward in space and compute a locally feasible path at each update iteration. Controllers can be written to: The general task in Nav2 for a controller is to compute a valid control effort to follow the global plan. However, many classes of controllers and local planners exist. It is the goal of this project that all controller algorithms can be plugins in this server for common research and industrial tasks.


key: chroma:document
string_value:
## Behaviors Recovery behaviors are a mainstay of fault-tolerant systems. The goal of recoveries are to deal with unknown or failure conditions of the system and autonomously handle them. Examples may include faults in the perception system resulting in the environmental representation being full of fake obstacles. The clear costmap recovery would then be triggered to allow the robot to move. Another example would be if the robot was stuck due to dynamic obstacles or poor control. Backing up or spinning in place, if permissible, allow the robot to move from a poor location into free space it may navigate successfully. Finally, in the case of a total failure, a recovery may be implemented to call an operator’s attention for help. This can be done via email, SMS, Slack, Matrix, etc. It is important to note that the behavior server can hold any behavior to share access to expensive resources like costmaps or TF buffers, not just recovery behaviors. Each may have its own API.


key: chroma:document
string_value:
## Smoothers As criteria for optimality of the path searched by a planner are usually reduced compared to reality, additional path refinement is often beneficial. Smoothers have been introduced for this purpose, typically responsible for reducing path raggedness and smoothing abrupt rotations, but also for increasing distance from obstacles and high-cost areas as the smoothers have access to a global environmental representation. Use of a separate smoother over one that is included as part of a planner is advantageous when combining different planners with different smoothers or when a specific control over smoothing is required, e.g. smoothing only a specific part of the path. The general task in Nav2 for a smoother is to receive a path and return its improved version. However, for different input paths, criteria of the improvements and methods of acquiring them exist, creating space for a multitude of smoothers that can be registered in this server.


key: chroma:document
string_value:
## Robot Footprints It is worth remarking that in the cost maps, we set a robot’s footprint either as a circle of radiusrobot_radiusor as a vector of pointsfootprintrepresenting an arbitrary polygon if the robot is non-circular. This can also be adjusted over time using the costmap’s~/footprinttopic, which will update the polygon over time as needed due to changes in the robot’s state, such as movement of an attached manipulator, picking up a pallet, or other actions that adjust a robot’s shape. That polygon will then automatically be used by the planners and controllers.


key: chroma:document
string_value:
## Waypoint Following Waypoint following is a basic feature of a navigation system. It tells our system how to use navigation to get to multiple destinations. Thenav2_waypoint_followercontains a waypoint following program with a plugin interface for specific task executors. This is useful if you need to go to a given location and complete a specific task like take a picture, pick up a box, or wait for user input. It is a nice demo application for how to use Nav2 in a sample application. However, it could be used for more than just a sample application. There are 2 schools of thoughts for fleet managers / dispatchers: In the first, thenav2_waypoint_followeris fully sufficient to create a production-grade on-robot solution. Since the autonomy system / dispatcher is taking into account things like the robot’s pose, battery level, current task, and more when assigning tasks, the application on the robot just needs to worry about the task at hand and not the other complexities of the system to complete the


key: chroma:document
string_value:
and not the other complexities of the system to complete the requested task. In this situation, you should think of a request to the waypoint follower as 1 unit of work (e.g. 1 pick in a warehouse, 1 security patrole loop, 1 aisle, etc) to do a task and then return to the dispatcher for the next task or request to recharge. In this school of thought, the waypoint following application is just one step above navigation and below the system autonomy application. In the second, thenav2_waypoint_followeris a nice sample application / proof of concept, but you really need your waypoint following / autonomy system on the robot to carry more weight in making a robust solution. In this case, you should use thenav2_behavior_treepackage to create a custom application-level behavior tree using navigation to complete the task. This can include subtrees like checking for the charge status mid-task for returning to dock or handling more than 1 unit of work in a more complex task. Soon, there will be


key: chroma:document
string_value:
than 1 unit of work in a more complex task. Soon, there will be anav2_bt_waypoint_follower(name subject to adjustment) that will allow you to create this application more easily. In this school of thought, the waypoint following application is more closely tied to the system autonomy, or in many cases, is the system autonomy. Neither is better than the other, it highly depends on the tasks your robot(s) are completing, in what type of environment, and with what cloud resources available. Often this distinction is very clear for a given business case. nav2_waypoint_followeralso supports GPS waypoint following when global localization is provided byrobot_localizationusing thenavsat_transformnode - but also may be provided by Fuse or any number of other sources. There is an action server named/follow_gps_waypointswithinnav2_waypoint_followerthat can directly take in goals expressed in GPS coordinates, convert them to cartesian goals in the global frame, and execute them as cartesian waypoints.


key: chroma:document
string_value:
## State Estimation Within the navigation project, there are 2 major transformations that need to be provided, according to community standards. Themaptoodomtransform is provided by a positioning system (localization, mapping, SLAM) andodomtobase_linkby an odometry system.


key: chroma:document
string_value:
## Standards REP 105defines the frames and conventions required for navigation and the larger ROS ecosystem. These conventions should be followed at all times to make use of the rich positioning, odometry, and SLAM projects available in the community. In a nutshell, REP-105 says that you must, at minimum, build a TF tree that contains a fullmap->odom->base_link->[sensorframes]for your robot. TF2 is the time-variant transformation library in ROS 2 we use to represent and obtain time synchronized transformations. It is the job of the global positioning system (GPS, SLAM, Motion Capture) to, at minimum, provide themap->odomtransformation. It is then the role of the odometry system to provide theodom->base_linktransformation. The remainder of the transformations relative tobase_linkshould be static and defined in yourURDF.


key: chroma:document
string_value:
## Global Positioning: Localization and SLAM It is the job of the global positioning system (GPS, SLAM, Motion Capture) to, at minimum, provide themap->odomtransformation. We provideamclwhich is an Adaptive Monte-Carlo Localization technique based on a particle filter for localization in a static map. We also provide SLAM Toolbox as the default SLAM algorithm for use to position and generate a static map. These methods may also produce other output including position topics, maps, or other metadata, but they must provide that transformation to be valid. Multiple positioning methods can be fused together using robot localization, discussed more below.


key: chroma:document
string_value:
## Odometry It is the role of the odometry system to provide theodom->base_linktransformation. Odometry can come from many sources including LIDAR, RADAR, wheel encoders, VIO, and IMUs. The goal of the odometry is to provide a smooth and continuous local frame based on robot motion. The global positioning system will update the transformation relative to the global frame to account for the odometric drift. Robot Localizationis typically used for this fusion. It will take inNsensors of various types and provide a continuous and smooth odometry to TF and to a topic. A typical mobile robotics setup may have odometry from wheel encoders, IMUs, and vision fused in this manner. The smooth output can be used then for dead-reckoning for precise motion and updating the position of the robot accurately between global position updates.


key: chroma:document
string_value:
## Environmental Representation The environmental representation is the way the robot perceives its environment. It also acts as the central localization for various algorithms and data sources to combine their information into a single space. This space is then used by the controllers, planners, and recoveries to compute their tasks safely and efficiently.


key: chroma:document
string_value:
## Costmaps and Layers The current environmental representation is a costmap. A costmap is a regular 2D grid of cells containing a cost from unknown, free, occupied, or inflated cost. This costmap is then searched to compute a global plan or sampled to compute local control efforts. Various costmap layers are implemented as pluginlib plugins to buffer information into the costmap. This includes information from LIDAR, RADAR, sonar, depth images, etc. It may be wise to process sensor data before inputting it into the costmap layer, but that is up to the developer. Costmap layers can be created to detect and track obstacles in the scene for collision avoidance using camera or depth sensors. Additionally, layers can be created to algorithmically change the underlying costmap based on some rule or heuristic. Finally, they may be used to buffer live data into the 2D or 3D world for binary obstacle marking.


key: chroma:document
string_value:
## Costmap Filters Imagine, you’re annotating a map file (or any image file) in order to have a specific action occur based on the location in the annotated map. Examples of marking/annotating might be keep out zones to avoid planning inside, or have pixels belong to maximum speeds in marked areas. This annotated map is called “filter mask”. Just like a mask overlaid on a surface, it can or cannot be same size, pose and scale as a main map. The main goal of filter mask - is to provide the ability of marking areas on maps with some additional features or behavioral changes. Costmap filters are a costmap layer-based approach of applying spatial-dependent behavioral changes, annotated in filter masks, into the Nav2 stack. Costmap filters are implemented as costmap plugins. These plugins are called “filters” as they are filtering a costmap by spatial annotations marked on filter masks. In order to make a filtered costmap and change a robot’s behavior in annotated areas, the filter plugin reads the data coming


key: chroma:document
string_value:
in annotated areas, the filter plugin reads the data coming from the filter mask. This data is being linearly transformed into a feature map in a filter space. Having this transformed feature map along with a map/costmap, any sensor data and current robot coordinate filters can update the underlying costmap and change the behavior of the robot depending on where it is. For example, the following functionality could be made by use of costmap filters:


key: chroma:document
string_value:
## Other Forms Various other forms of environmental representations exist. These include:

## Nav2 Academic Overview


key: chroma:document
string_value:
Title: RotateToGoalCritic

URL: https://docs.nav2.org/configuration/packages/trajectory_critics/rotate_to_goal.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Parameters <dwbplugin>: DWB plugin name defined in thecontroller_plugin_idsparameter inController Server. <name>: RotateToGoalCritic critic name defined in the<dwb plugin>.criticsparameter defined inDWB Controller.


key: chroma:document
string_value:
Title: ClearCostmapAroundRobot

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/ClearCostmapAroundRobot.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<ClearCostmapAroundRobot

name=

"ClearLocalCostmap

Subtree"

service_name=

"local_costmap/clear_around_local_costmap"

/>

```


key: chroma:document
string_value:
Title: Smac State Lattice Planner

URL: https://docs.nav2.org/configuration/packages/smac/configuring-smac-lattice.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Parameters

## Example

Code Examples:

Language: unknown

File: >=1

```

planner_server

:

ros__parameters

:

planner_plugins

:

[

"GridBased"

]

use_sim_time

:

True

GridBased

:

plugin

:

"nav2_smac_planner::SmacPlannerLattice"

# In Iron and older versions, "/" was used instead of "::"

allow_unknown

:

true

# Allow traveling in unknown space

tolerance

:

0.25

# dist-to-goal heuristic cost (distance) for valid tolerance endpoints if exact goal cannot be found.

max_iterations

:

1000000

# Maximum total iterations to search for before failing (in case unreachable), set to -1 to disable

max_on_approach_iterations

:

1000

# Maximum number of iterations after within tolerances to continue to try to find exact solution

max_planning_time

:

5.0


key: chroma:document
string_value:
max_planning_time

:

5.0

# Max time in s for planner to plan, smooth

analytic_expansion_ratio

:

3.5

# The ratio to attempt analytic expansions during search for final approach.

analytic_expansion_max_length

:

3.0

# For Hybrid/Lattice nodes The maximum length of the analytic expansion to be considered valid to prevent unsafe shortcutting

analytic_expansion_max_cost

:

200.0

# The maximum single cost for any part of an analytic expansion to contain and be valid, except when necessary on approach to goal

analytic_expansion_max_cost_override

:

false

#  Whether or not to override the maximum cost setting if within critical distance to goal (ie probably required)

reverse_penalty

:

2.0

# Penalty to apply if motion is reversing, must be => 1

change_penalty

:

0.05

# Penalty to apply if motion is changing directions (L to R), must be >= 0

non_straight_penalty

:

1.05

# Penalty to apply if motion is non-straight, must be => 1

cost_penalty

:

2.0


key: chroma:document
string_value:
cost_penalty

:

2.0

# Penalty to apply to higher cost areas when adding into the obstacle map dynamic programming distance expansion heuristic. This drives the robot more towards the center of passages. A value between 1.3 - 3.5 is reasonable.

rotation_penalty

:

5.0

# Penalty to apply to in-place rotations, if minimum control set contains them

retrospective_penalty

:

0.015

lattice_filepath

:

""

# The filepath to the state lattice graph

lookup_table_size

:

20.0

# Size of the dubin/reeds-sheep distance window to cache, in meters.

cache_obstacle_heuristic

:

false

# Cache the obstacle map dynamic programming distance expansion heuristic between subsequent replannings of the same goal location. Dramatically speeds up replanning performance (40x) if costmap is largely static.

allow_reverse_expansion

:

false

# If true, allows the robot to use the primitives to expand in the mirrored opposite direction of the current robot's orientation (to reverse).

smooth_path

:

True


key: chroma:document
string_value:
smooth_path

:

True

# If true, does a simple and quick smoothing post-processing to the path

smoother

:

max_iterations

:

1000

w_smooth

:

0.3

w_data

:

0.2

tolerance

:

1.0e-10

do_refinement

:

true

refinement_num

:

2

```


key: chroma:document
string_value:
Title: Simple Smoother

URL: https://docs.nav2.org/configuration/packages/configuring

simple

smoother.html#example

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Simple Smoother Parameters

## Example

Code Examples:

Language: unknown

File: >=1

```

smoother_server

:

ros__parameters

:

costmap_topic

:

global_costmap/costmap_raw

footprint_topic

:

global_costmap/published_footprint

robot_base_frame

:

base_link

transform_timeout

:

0.1

smoother_plugins

:

[

"simple_smoother"

]

simple_smoother

:

plugin

:

"nav2_smoother::SimpleSmoother"

tolerance

:

1.0e

10

do_refinement

:

True

refinement_num

:

2

max_its

:

1000

w_data

:

0.2

w_smooth

:

0.3

```


key: chroma:document
string_value:
Title: SingleTrigger

URL: https://docs.nav2.org/configuration/packages/bt

plugins/decorators/SingleTrigger.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<SingleTrigger>

<!-

Add tree components here--

>

</SingleTrigger>

```


key: chroma:document
string_value:
Title: Adding a Smoother to a BT

URL: https://docs.nav2.org/tutorials/docs/adding_smoother.html#requirements

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Overview

This tutorial shows how to add a smoother to your behavior tree to smooth output paths from a path planner.

Before completing this tutorials, completingGetting Startedis highly recommended especially if you are new to ROS and Nav2.

## Requirements

You must install Nav2, Turtlebot3.

If you don’t have them installed, please followGetting Started.

You must also have a working behavior tree, such as those provided by the Nav2 BT Navigator package, for editing.

You should also have a copy of thenav2_params.yamlfile for your system to edit as well.

## Tutorial Steps

## 0- Familiarization with the Smoother BT Node


key: chroma:document
string_value:
## 0- Familiarization with the Smoother BT Node

TheSmoothPathBT node is a behavior tree node that interacts with the smoother task server similar to that which you may expect to find for the planner or controller servers. It contains the action client to call the server and specifies its arguments and return types as BT ports. It too calls the server via an action interface that may be separately interacted with via other servers and client library languages.

Please see the BT node’s configuration page to familiarize yourself with all aspects, but the core ports to note are theunsmoothed_pathinput port and thesmoothed_pathoutput port. The first takes in a raw path from a planning algorithm and the latter will set the value of the smoothed output path post-smoothing. Other ports are available that fully implements the Smoother Server’s action API.

## 1- Specifying a Smoother Plugin


key: chroma:document
string_value:
## 1- Specifying a Smoother Plugin

In order to use a smoother in your BT node, you must first configure the smoother server itself to contain the smoother plugins of interest. These plugins implement the specific algorithms that you would like to use.

For each smoother plugin you would like to use, a name must be given to it (e.g.simple_smoother,curvature_smoother). This name is itssmoother_idfor other servers to interact with this algorithm from a request to the Smoother Server’s action interface.

Under each name, the parameters for that particular algorithm must be specified along with thepluginname for pluginlib to load a given algorithm’s library. An example configuration of 2 smoother plugins is shown below that could be used in thenav2_params.yamlfor your robot.

## 2- Modifying your BT XML


key: chroma:document
string_value:
## 2- Modifying your BT XML

Now that you have selected and configured the smoother server for your given plugin(s), it is time to use those smoother(s) in your behavior tree for navigation behavior. While there are many places / ways to use this in a BT, what is shown below is probably the most likely situation you would want to use the smoother in (to smooth a path returned by the path planner and then using that smoothed path for path tracking).

Note: If you use only a single type of smoothing algorithm, there is no need to specify thesmoother_idin the BT XML entry. Since there is only a single option, that will be used for any request that does not specifically request a smoother plugin. However, if you leverage multiple smoother plugins, youmustpopulate thesmoother_idXML port.

A given behavior tree will have a line:


key: chroma:document
string_value:
A given behavior tree will have a line:

This line calls the planner server and return a path to thepathblackboard variable in the behavior tree. We are  going to replace that line with the following to compute the path, smooth the path, and finally replace thepathblackboard variable with the new smoothed path that the system will now interact with:

If you wish to have recoveries for the smoother error codes, such as triggering the system recoveries branch of a behavior tree:

And its as simple as that! You can now compile or use this behavior tree in your system and see that the plans are now smoothed and the controllers are now tracking this smoothed path. The image at the top of the tutorial shows the unsmoothed path from NavFn (red) and the smoothed path (black). Note the smoother approach to goal, turns, and transitions in the straight-line segments.


key: chroma:document
string_value:
If you wish to see the difference, but not track the smoothed path, you may wish to remove thesmoothed_path="{path}"portion to compute the smoothed path, but not replace the original path with it. Instead, the topic/smoothed_pathcontains this information published by the smoother server for visualization or use by other parts of the system. You may also remap the smoothed path to another blackboard variable to interact with it in other parts of the behavior tree (e.g.smoothed_path="{smoothed_path}").

Code Examples:

Language: unknown

File: nav2_params.yaml

```

smoother_server

:

ros__parameters

:

costmap_topic

:

global_costmap/costmap_raw

footprint_topic

:

global_costmap/published_footprint

robot_base_frame

:

base_link

transform_timeout

:

0.1

smoother_plugins

:

[

"simple_smoother"

,

"curvature_smoother"

]

simple_smoother

:

plugin

:

"nav2_smoother::SimpleSmoother"

tolerance

:

1.0e-10

do_refinement

:

True

curvature_smoother

:

plugin

:


key: chroma:document
string_value:
do_refinement

:

True

curvature_smoother

:

plugin

:

"nav2_ceres_costaware_smoother/CeresCostawareSmoother"

```

Language: unknown

File: smoother_id

```

<ComputePathToPose

goal=

"{goal}"

path=

"{path}"

planner_id=

"GridBased"

error_code_id=

"{compute_path_error_code}"

/>

```

Language: unknown

File: path

```

<Sequence

name=

"ComputeAndSmoothPath"

>

<ComputePathToPose

goal=

"{goal}"

path=

"{path}"

planner_id=

"GridBased"

error_code_id=

"{compute_path_error_code}"

/>

<SmoothPath

unsmoothed_path=

"{path}"

smoothed_path=

"{path}"

error_code_id=

"{smoother_error_code}"

/>

</Sequence>

```

Language: unknown

File: path

```

<Sequence

name=

"TryToResolveSmootherErrorCodes"

>

<WouldASmootherRecoveryHelp

error_code=

"{smoother_error_code}"

>

<!-- recovery to resolve smoother error code goes here -->

<Sequence/>

```


key: chroma:document
string_value:
Title: Writing a New Planner Plugin

URL: https://docs.nav2.org/plugin_tutorials/docs/writing_new_nav2planner_plugin.html#writing-new-nav2planner-plugin

Section: tuning/index.html

--------------------------------------------------------------------------------

## Overview

This tutorial shows how to create your own planner plugin.

## Requirements

## Tutorial Steps

## 1- Creating a new Planner Plugin

We will create a simple straight-line planner.

The annotated code in this tutorial can be found innavigation_tutorialsrepository as thenav2_straightline_planner.

This package can be considered as a reference for writing planner plugin.

Our example plugin inherits from the base classnav2_core::GlobalPlanner. The base class provides 5 pure virtual methods to implement a planner plugin. The plugin will be used by the planner server to compute trajectories.

Let’s learn more about the methods needed to write a planner plugin.


key: chroma:document
string_value:
For this tutorial, we will be using methodsStraightLine::configure()andStraightLine::createPlan()to create straight-line planner.

In planners,configure()method must set member variables from ROS parameters and any initialization required,

Here,name_+".interpolation_resolution"is fetching the ROS parametersinterpolation_resolutionwhich is specific to our planner. Nav2 allows the loading of multiple plugins, and to keep things organized, each plugin is mapped to some ID/name. Now if we want to retrieve the parameters for that specific plugin, we use<mapped_name_of_plugin>.<name_of_parameter>as done in the above snippet. For example, our example planner is mapped to the name “GridBased” and to retrieve theinterpolation_resolutionparameter which is specific to “GridBased”, we usedGridbased.interpolation_resolution. In other words,GridBasedis used as a namespace for plugin-specific parameters. We will see more on this when we discuss the parameters file (or params file).


key: chroma:document
string_value:
IncreatePlan()method, we need to create a path from the given start to goal poses. TheStraightLine::createPlan()is called using start pose and goal pose to solve the global path planning problem. Upon succeeding, it converts the path to thenav_msgs::msg::Pathand returns to the planner server. Below annotation shows the implementation of this method.

The remaining methods are not used but it’s mandatory to override them. As per the rules, we did override all but left them blank.

## 2- Exporting the planner plugin

Now that we have created our custom planner, we need to export our planner plugin so that it will be visible to the planner server. Plugins are loaded at runtime and if they are not visible, then our planner server won’t be able to load it. In ROS 2, exporting and loading plugins is handled bypluginlib.

Coming back to our tutorial, classnav2_straightline_planner::StraightLineis loaded dynamically asnav2_core::GlobalPlannerwhich is our base class.


key: chroma:document
string_value:
Note that it requires pluginlib to export out plugin’s class. Pluginlib would provide as macroPLUGINLIB_EXPORT_CLASSwhich does all the work of exporting.

It is good practice to place these lines at the end of the file, but technically, you can also write at the top.

## 3- Pass the plugin name through params file

To enable the plugin, we need to modify thenav2_params.yamlfile as below to replace following params

with

In the above snippet, you can observe the mapping of ournav2_straightline_planner::StraightLineplanner to its idGridBased. To pass plugin-specific parameters, we have used<plugin_id>.<plugin_specific_parameter>.

## 4- Run StraightLine plugin

Run Turtlebot3 simulation with enabled navigation2. Detailed instruction how to make it are written atGetting Started. Below is shortcut command for that:


key: chroma:document
string_value:
Then goto RViz and click on the “2D Pose Estimate” button at the top and point to the location on map as it was described inGetting Started. Robot will localize on the map and then click on “Navigation2 goal” and click on the pose where you want your planner to consider a goal pose. After that planner will plan the path and robot will start moving towards the goal.

Code Examples:

Language: unknown

File: configure()

```

node_

=

parent

;

tf_

=

tf

;

name_

=

name

;

costmap_

=

costmap_ros

>

getCostmap

();

global_frame_

=

costmap_ros

>

getGlobalFrameID

();

// Parameter initialization

nav2_util

::

declare_parameter_if_not_declared

(

node_

,

name_

+

".interpolation_resolution"

,

rclcpp

::

ParameterValue

(

0.1

));

node_

>

get_parameter

(

name_

+

".interpolation_resolution"

,

interpolation_resolution_

);

```

Language: unknown

File: nav_msgs::msg::Path

```

nav_msgs

::

msg

::

Path

global_path

;


key: chroma:document
string_value:
```

nav_msgs

::

msg

::

Path

global_path

;

// Checking if the goal and start state is in the global frame

if

(

start

.

header

.

frame_id

!=

global_frame_

)

{

RCLCPP_ERROR

(

node_

>

get_logger

(),

"Planner will only except start position from %s frame"

,

global_frame_

.

c_str

());

return

global_path

;

}

if

(

goal

.

header

.

frame_id

!=

global_frame_

)

{

RCLCPP_INFO

(

node_

>

get_logger

(),

"Planner will only except goal position from %s frame"

,

global_frame_

.

c_str

());

return

global_path

;

}

global_path

.

poses

.

clear

();

global_path

.

header

.

stamp

=

node_

>

now

();

global_path

.

header

.

frame_id

=

global_frame_

;

// calculating the number of loops for current value of interpolation_resolution_

int

total_number_of_loop

=

std

::

hypot

(

goal

.

pose

.

position

.

x

start

.

pose

.

position

.

x

,

goal

.

pose

.

position

.

y

start

.

pose

.

position

.

y

)

/

interpolation_resolution_

;


key: chroma:document
string_value:
.

pose

.

position

.

y

)

/

interpolation_resolution_

;

double

x_increment

=

(

goal

.

pose

.

position

.

x

start

.

pose

.

position

.

x

)

/

total_number_of_loop

;

double

y_increment

=

(

goal

.

pose

.

position

.

y

start

.

pose

.

position

.

y

)

/

total_number_of_loop

;

for

(

int

i

=

0

;

i

<

total_number_of_loop

;

++

i

)

{

geometry_msgs

::

msg

::

PoseStamped

pose

;

pose

.

pose

.

position

.

x

=

start

.

pose

.

position

.

x

+

x_increment

i

;

pose

.

pose

.

position

.

y

=

start

.

pose

.

position

.

y

+

y_increment

i

;

pose

.

pose

.

position

.

z

=

0.0

;

pose

.

pose

.

orientation

.

x

=

0.0

;

pose

.

pose

.

orientation

.

y

=

0.0

;

pose

.

pose

.

orientation

.

z

=

0.0

;

pose

.

pose

.

orientation

.

w

=

1.0

;

pose

.

header

.

stamp

=

node_

>

now

();

pose

.

header

.

frame_id

=

global_frame_

;

global_path

.

poses

.

push_back

(

pose

);

}


key: chroma:document
string_value:
;

global_path

.

poses

.

push_back

(

pose

);

}

global_path

.

poses

.

push_back

(

goal

);

return

global_path

;

```

Language: unknown

File: nav2_core::GlobalPlanner

```

#include

"pluginlib/class_list_macros.hpp"

PLUGINLIB_EXPORT_CLASS

(

nav2_straightline_planner

::

StraightLine

,

nav2_core

::

GlobalPlanner

)

```

Language: unknown

File: description

```

<library

path=

"nav2_straightline_planner_plugin"

>

<class

type=

"nav2_straightline_planner::StraightLine"

base_class_type=

"nav2_core::GlobalPlanner"

>

<description>

This

is

an

example

plugin

which

produces

straight

path.

</description>

</class>

</library>

```

Language: unknown

File: share

```

pluginlib_export_plugin_description_file(nav2_core global_planner_plugin.xml)

```

Language: unknown

File: package.xml

```

<export>

<build_type>

ament_cmake

</build_type>

<nav2_core

plugin=

"${prefix}/global_planner_plugin.xml"

/>

</export>

```

Language: unknown

File: plugin:MyPlugin::Plugin


key: chroma:document
string_value:
```

Language: unknown

File: plugin:MyPlugin::Plugin

```

planner_server:

ros__parameters:

plugins: ["GridBased"]

use_sim_time: True

GridBased:

plugin: "nav2_navfn_planner::NavfnPlanner" # For Foxy and later. In Iron and older versions, "/" was used instead of "::"

tolerance: 2.0

use_astar: false

allow_unknown: true

```

Language: unknown

File: plugin:MyPlugin::Plugin

```

planner_server:

ros__parameters:

plugins: ["GridBased"]

use_sim_time: True

GridBased:

plugin: "nav2_straightline_planner::StraightLine"

interpolation_resolution: 0.1

```

Language: unknown

File: <plugin_id>.<plugin_specific_parameter>

```

$

ros2

launch

nav2_bringup

tb3_simulation_launch.py

params_file:

=

/path/to/your_params_file.yaml

```


key: chroma:document
string_value:
Title: Denoise Layer Parameters

URL: https://docs.nav2.org/configuration/packages/costmap

plugins/denoise.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: <denoiselayer>

```

local_costmap

:

local_costmap

:

ros__parameters

:

...

plugins

:

[

"voxel_layer"

,

"denoise_layer"

,

"inflation_layer"

]

...

denoise_layer

:

plugin

:

"nav2_costmap_2d::DenoiseLayer"

enabled

:

true

minimal_group_size

:

2

group_connectivity_type

:

8

```


key: chroma:document
string_value:
Title: WouldAControllerRecoveryHelp

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/WouldAControllerRecoveryHelp.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Port

## Example

Code Examples:

Language: unknown

File: FAILURE

```

<WouldAControllerRecoveryHelp

error_code=

"{follow_path_error_code}"

/>

```


key: chroma:document
string_value:
Title: Regulated Pure Pursuit

URL: https://docs.nav2.org/configuration/packages/configuring-regulated-pp.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Regulated Pure Pursuit Parameters

## Example

Code Examples:

Language: unknown

File: true

```

controller_server

:

ros__parameters

:

use_sim_time

:

True

controller_frequency

:

20.0

min_x_velocity_threshold

:

0.001

min_y_velocity_threshold

:

0.5

min_theta_velocity_threshold

:

0.001

progress_checker_plugins

:

[

"progress_checker"

]

# progress_checker_plugin: "progress_checker" For Humble and older

goal_checker_plugins

:

[

"goal_checker"

]

controller_plugins

:

[

"FollowPath"

]

progress_checker

:

plugin

:

"nav2_controller::SimpleProgressChecker"

required_movement_radius

:

0.5

movement_time_allowance

:

10.0

goal_checker

:

plugin

:

"nav2_controller::SimpleGoalChecker"

xy_goal_tolerance

:

0.25

yaw_goal_tolerance

:

0.25


key: chroma:document
string_value:
xy_goal_tolerance

:

0.25

yaw_goal_tolerance

:

0.25

stateful

:

True

FollowPath

:

plugin

:

"nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController"

desired_linear_vel

:

0.5

lookahead_dist

:

0.6

min_lookahead_dist

:

0.3

max_lookahead_dist

:

0.9

lookahead_time

:

1.5

rotate_to_heading_angular_vel

:

1.8

transform_tolerance

:

0.1

use_velocity_scaled_lookahead_dist

:

false

min_approach_linear_velocity

:

0.05

approach_velocity_scaling_dist

:

0.6

use_collision_detection

:

true

max_allowed_time_to_collision_up_to_carrot

:

1.0

use_regulated_linear_velocity_scaling

:

true

use_fixed_curvature_lookahead

:

false

curvature_lookahead_dist

:

0.25

use_cost_regulated_linear_velocity_scaling

:

false

regulated_linear_scaling_min_radius

:

0.9

regulated_linear_scaling_min_speed

:

0.25

use_rotate_to_heading

:

true

allow_reversing

:

false

rotate_to_heading_min_angle

:

0.785

max_angular_accel

:

3.2

max_robot_pose_search_dist

:

10.0

```


key: chroma:document
string_value:
Title: InputAtWaypoint

URL: https://docs.nav2.org/configuration/packages/nav2_waypoint_follower

plugins/input_at_waypoint.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Parameters <nav2_waypoint_followerplugin>: nav2_waypoint_follower plugin name defined in thewaypoint_task_executor_plugin_idparameter inWaypoint Follower.


key: chroma:document
string_value:
Title: TimeExpired

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/TimeExpired.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<TimeExpired

seconds=

"1.0"

/>

```


key: chroma:document
string_value:
Title: (STVL) Using an External Costmap Plugin

URL: https://docs.nav2.org/tutorials/docs/navigation2_with_stvl.html#setup

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Overview

This tutorial shows how to load and use an external plugin.

This example uses theSpatio Temporal Voxel Layer(STVL) costmappluginlibplugin as an example.

STVL is a demonstrative pluginlib plugin and the same process can be followed for other costmap plugins as well as plugin planners, controllers, and behaviors.

Before completing this tutorial, please look at the previous two tutorials on navigation in simulation and physical hardware, if available.

This tutorial assumes knowledge of navigation and basic understanding of costmaps.

## Costmap2D and STVL

Costmap 2D is the data object we use to buffer sensor information into a global view that the robot will use to create plans and control efforts.


key: chroma:document
string_value:
Within Costmap2D, there are pluginlib plugin interfaces available to create custom behaviors loadable at runtime.

Examples of included pluginlib plugins for Costmap2D are the Obstacle Layer, Voxel Layer, Static Layer, and Inflation Layer.

However, these are simply example plugins offered by the base implementation.

Another available pluginlib plugin for Costmap2D in Navigation2 is STVL.

STVL is another 3D perception plugin similar to the Voxel Layer.

A more detailed overview of how it works can be foundin this repo, however it buffers 3D data from depth cameras, sonars, lidars, and more into a sparse volumetic world model and removes voxels over time proportional with a sensor model and time-based expiration.

This can be especially useful for robots in highly dynamic environments and decreases the resource utilization for 3D sensor processing by up to 2x.

STVL also treats 3D lidars and radars as first class citizens for support.

The ROSCon talk for STVL can be foundin this video.

## Tutorial Steps


key: chroma:document
string_value:
## Tutorial Steps

## 0- Setup

Follow the same process as inGetting Startedfor installing and setting up a robot for hardware testing or simulation, as applicable. Ensure ROS 2, Navigation2, and Gazebo are installed.

## 1- Install STVL

STVL can be installed in ROS 2 via the ROS Build Farm:

It can also be built from source by cloning the repository into your Navigation2 workspace:

## 1- Modify Navigation2 Parameter

STVL is an optional plugin, like all plugins, in Costmap2D. Costmap Plugins in Navigation2 are loaded in theplugin_namesandplugin_typesvariables inside of their respective costmaps.

For example, the following will load the static and obstacle layer plugins into the namestatic_layerandobstacle_layer, respectively:

To load the STVL plugin, a new plugin name and type must be added.

For example, if the application required an STVL layer and no obstacle layer, our file would be:


key: chroma:document
string_value:
Similar to the Voxel Layer, after registering the plugin, we can add the configuration of the STVL layer under the namespacestvl_layer.

An example fully-described parameterization of an STVL configuration is:

Please copy-paste the text above, with theplugin_namesandplugin_typesregistration, into yournav2_params.yamlto enable STVL in your application.

Make sure to change both the local and global costmaps.

Note: Pluginlib plugins for other Navigation2 servers such as planning, behavior, and control can be set in this same way.

## 2- Launch Navigation2

Follow the same process as inGetting Startedto launch a simulated robot in gazebo with Navigation2.

Navigation2 is now using STVL as its 3D sensing costmap layer.

## 3-  RVIZ

With RViz open andpublish_voxel_map:true, you can visualize the underlying data structure’s 3D grid using the{local,global}_costmap/voxel_gridtopics.


key: chroma:document
string_value:
Note: It is recommended in RViz to set thePointCloud2Size to your voxel size and the style toBoxeswith a neutral color for best visualization.

Code Examples:

Language: unknown

File: obstacle_layer

```

global_costmap

:

global_costmap

:

ros__parameters

:

use_sim_time

:

True

plugins

:

[

"static_layer"

,

"obstacle_layer"

]

```

Language: unknown

File: plugin:MyPlugin::Plugin

```

global_costmap

:

global_costmap

:

ros__parameters

:

use_sim_time

:

True

plugins

:

[

"static_layer"

,

"stvl_layer"

]

```

Language: unknown

File: stvl_layer

```

stvl_layer

:

plugin

:

"spatio_temporal_voxel_layer/SpatioTemporalVoxelLayer"

enabled

:

true

voxel_decay

:

15.

decay_model

:

0

voxel_size

:

0.05

track_unknown_space

:

true

unknown_threshold

:

15

mark_threshold

:

0

update_footprint_enabled

:

true

combination_method

:

1

origin_z

:

0.0

publish_voxel_map

:

true

transform_tolerance

:

0.2

mapping_mode

:

false

map_save_duration

:

60.0


key: chroma:document
string_value:
:

0.2

mapping_mode

:

false

map_save_duration

:

60.0

observation_sources

:

pointcloud

pointcloud

:

data_type

:

PointCloud2

topic

:

/intel_realsense_r200_depth/points

marking

:

true

clearing

:

true

obstacle_range

:

3.0

min_obstacle_height

:

0.0

max_obstacle_height

:

2.0

expected_update_rate

:

0.0

observation_persistence

:

0.0

inf_is_valid

:

false

filter

:

"voxel"

voxel_min_points

:

0

clear_after_reading

:

true

max_z

:

7.0

min_z

:

0.1

vertical_fov_angle

:

0.8745

horizontal_fov_angle

:

1.048

decay_acceleration

:

15.0

model_type

:

0

```


key: chroma:document
string_value:
Title: CancelControl

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/CancelControl.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: server_name

```

<CancelControl

server_name=

"FollowPath"

server_timeout=

"10"

/>

```


key: chroma:document
string_value:
Title: CancelBackUp

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/CancelBackUp.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: backup

```

<CancelBackUp

server_name=

"BackUp"

server_timeout=

"10"

/>

```


key: chroma:document
string_value:
Title: Smac Planner

URL: https://docs.nav2.org/configuration/packages/configuring

smac

planner.html#provided

plugins

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Provided Plugins


key: chroma:document
string_value:
## Description Thenav2_smac_plannerpackage contains an optimized templated A* search algorithm used to create multiple A*-based planners for multiple types of robot platforms. It uses template node types to develop different search-based planners. We support circular differential-drive and omni-directional drive robots using theSmacPlanner2Dplanner which implements a cost-aware A* planner. We support car-like (ackermann) and legged vehicles using theSmacPlannerHybridplugin which implements a Hybrid-A* planner. We support non-circular, arbitrary shaped, any model vehicles using theSmacPlannerLatticeplugin which implements a State Lattice planner (e.g. omni, diff, ackermann, legged, custom). It contains control sets and generators for ackermann, legged, differential drive and omnidirectional vehicles, but you may provide your own for another robot type or to have different planning behaviors. The last two plugins are bothkinematically feasibleand supportreversing. They have performance similar to its 2D


key: chroma:document
string_value:
supportreversing. They have performance similar to its 2D counter parts like 2D-A* and NavFn via highly optimized heuristic functions and efficient programming. An example of the 3 planners can be seen below, planning a roughly 75 m path. Usual planning times are below 100ms for some environments, occasionally approaching up to 200ms. The performance of all 3 planners is roughly comparable with naive 2D search algorithms that have long been mainstays of the ROS Navigation ecosystem, but also achieving kinematic feasibility, support for reversing, and using modern state of the art techniques.


key: chroma:document
string_value:
Title: General Tutorials

URL: https://docs.nav2.org/tutorials/index.html

Section: tutorials/index.html

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Title: Constrained smoother

URL: https://docs.nav2.org/configuration/packages/configuring-constrained-smoother.html#smoother-server-parameters

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Smoother Server Parameters

## Example

Code Examples:

Language: unknown

File: DENSE_QR

```

smoother_server

:

ros__parameters

:

use_sim_time

:

True

smoother_plugins

:

[

"SmoothPath"

]

SmoothPath

:

plugin

:

"nav2_constrained_smoother/ConstrainedSmoother"

reversing_enabled

:

true

# whether to detect forward/reverse direction and cusps. Should be set to false for paths without orientations assigned

path_downsampling_factor

:

3

# every n-th node of the path is taken. Useful for speed-up

path_upsampling_factor

:

1

# 0 - path remains downsampled, 1 - path is upsampled back to original granularity using cubic bezier, 2... - more upsampling

keep_start_orientation

:

true


key: chroma:document
string_value:
keep_start_orientation

:

true

# whether to prevent the start orientation from being smoothed

keep_goal_orientation

:

true

# whether to prevent the gpal orientation from being smoothed

minimum_turning_radius

:

0.40

# minimum turning radius the robot can perform. Can be set to 0.0 (or w_curve can be set to 0.0 with the same effect) for diff-drive/holonomic robots

w_curve

:

30.0

# weight to enforce minimum_turning_radius

w_dist

:

0.0

# weight to bind path to original as optional replacement for cost weight

w_smooth

:

2000000.0

# weight to maximize smoothness of path

w_cost

:

0.015

# weight to steer robot away from collision and cost

# Parameters used to improve obstacle avoidance near cusps (forward/reverse movement changes)

w_cost_cusp_multiplier

:

3.0

# option to use higher weight during forward/reverse direction change which is often accompanied with dangerous rotations

cusp_zone_length

:

2.5


key: chroma:document
string_value:
cusp_zone_length

:

2.5

# length of the section around cusp in which nodes use w_cost_cusp_multiplier (w_cost rises gradually inside the zone towards the cusp point, whose costmap weight eqals w_cost*w_cost_cusp_multiplier)

# Points in robot frame to grab costmap values from. Format: [x1, y1, weight1, x2, y2, weight2, ...]

# IMPORTANT: Requires much higher number of iterations to actually improve the path. Uncomment only if you really need it (highly elongated/asymmetric robots)

# cost_check_points: [-0.185, 0.0, 1.0]

optimizer

:

max_iterations

:

70

# max iterations of smoother

debug_optimizer

:

false

# print debug info

gradient_tol

:

5e3

fn_tol

:

1.0e-15

param_tol

:

1.0e-20

```


key: chroma:document
string_value:
Title: Static Layer Parameters

URL: https://docs.nav2.org/configuration/packages/costmap

plugins/static.html

Section: getting_started/index.html

--------------------------------------------------------------------------------


key: chroma:document
string_value:
Title: ReinitializeGlobalLocalization

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/ReinitializeGlobalLocalization.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<ReinitializeGlobalLocalization

service_name=

"reinitialize_global_localization"

/>

```


key: chroma:document
string_value:
Title: CancelWait

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/CancelWait.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Example

Code Examples:

Language: unknown

File: wait

```

<CancelWait

server_name=

"Wait"

server_timeout=

"10"

/>

```


key: chroma:document
string_value:
Title: ObstacleFootprintCritic

URL: https://docs.nav2.org/configuration/packages/trajectory_critics/obstacle_footprint.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Parameters <dwbplugin>: DWB plugin name defined in thecontroller_plugin_idsparameter inController Server. <name>: ObstacleFootprintCritic critic name defined in the<dwb plugin>.criticsparameter defined inDWB Controller.


key: chroma:document
string_value:
Title: IsStuck

URL: https://docs.nav2.org/configuration/packages/bt

plugins/conditions/IsStuck.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Example

Code Examples:

Language: unknown

File: use_cancel_deceleration

```

<IsStuck/>

```


key: chroma:document
string_value:
Title: Spin

URL: https://docs.nav2.org/configuration/packages/bt

plugins/actions/Spin.html

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Input Ports

## Output Ports

## Example

Code Examples:

Language: unknown

File: Spin

```

<Spin

spin_dist=

"1.57"

server_name=

"spin"

server_timeout=

"10"

is_recovery=

"true"

error_code_id=

"{spin_error_code}"

/>

```


key: chroma:document
string_value:
Title: Velocity Smoother

URL: https://docs.nav2.org/configuration/packages/configuring-velocity-smoother.html#velocity-smoother-parameters

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Velocity Smoother Parameters

## Example

Code Examples:

Language: unknown

File: TwistStamped

```

velocity_smoother

:

ros__parameters

:

smoothing_frequency

:

20.0

scale_velocities

:

false

feedback

:

"OPEN_LOOP"

max_velocity

:

[

0.5

,

0.0

,

2.5

]

min_velocity

:

[

0.5

,

0.0

,

2.5

]

deadband_velocity

:

[

0.0

,

0.0

,

0.0

]

velocity_timeout

:

1.0

max_accel

:

[

2.5

,

0.0

,

3.2

]

max_decel

:

[

2.5

,

0.0

,

3.2

]

odom_topic

:

"odom"

odom_duration

:

0.1

use_realtime_priority

:

false

enable_stamped_cmd_vel

:

false

```


key: chroma:document
string_value:
Title: Using Docking Server

URL: https://docs.nav2.org/tutorials/docs/using_docking.html#overview

Section: getting_started/index.html

--------------------------------------------------------------------------------

## Overview

This tutorial shows how to use the Docking Server with Nav2 robot systems.

The Docking Server is a general framework which can be used with arbitrary types of robots and docks in order to auto-dock them.

This is accomplished via pluginsChargingDockandNonChargingDockwhich implement the dock specifics like detecting the pose of the dock using sensor data, how to detect when the robot is in contact with the dock, and when charging has successfully started.

A configuration of the docking server can contain a database of many docks of different pluginChargingDockandNonChargingDocktypes to handle a broad range of docking locations and hardware dock revisions.


key: chroma:document
string_value:
Included with the package is an exampleSimpleChargingDockandSimpleNonChargingDockplugins which contains features and methods very common for robot docking.

These support charging stations and docking with static infrastructure (ex. conveyor belts) or dynamic docking (ex pallets) locations.

It is likely that you may be able to use this as well rather than developing your own dock plugin to get started.

The docking procedure is as follows:

Thanks to NVIDIA for sponsoring this Docking Server package and this tutorial!

You can find how to dock your Nova Carter robot using Nav2 and this work in thenova_carter_docking package!

## Requirements

It is assumed ROS2 and Nav2 dependent packages are installed or built locally - includingopennav_docking.

Please make sure that Nav2 project is also built locally, seeBuild and Installfor reference.

Seeopennav_dockingREADME for complete concept explanations, parameters, and APIs.

## ChargingDock Plugins


key: chroma:document
string_value:
## ChargingDock Plugins

opennav_docking_core::ChargingDockandopennav_docking_core::ChargingDockplugins are established to abstract out robot- and dock-specifics from the generalized framework.

This allows a system to leverage this framework and provide its own methods for detecting the dock’s current pose, when the robot is charging, and when contact is made.

Luckily, there are several common ROS APIs that allow us to create semi-generalizedSimpleChargingDockandSimpleNonChargingDockplugins that allows out-of-the-box docking as long as users provideJointState,BatteryState, and detected dock posePoseStampedtopics.

However, one way or another, your system requires an applicableChargingDockorNonChargingDockplugin for each type of dock you wish to use.

The plugins has a few key APIs:

TheSimpleChargingDockprovides an implementation with common options for these APIs:


key: chroma:document
string_value:
Thus, for testing (no detection, no battery information, no joint state information) and realistic application (dock detection, battery status information, joint state information), this dock plugin can be used.

It can also be used when only some of the information if available as well.

If your robot or dock does not fall into these implementations (i.e. using custom battery or detection messages that cannot be converted into ROS standard types), then you may be required to build your own plugin to meet your particular needs.

However, you can use theSimpleChargingDockassuming you turn off these settings and dock blind to get started.

There is an equivalentSimpleNonChargingDockplugin for non-charging docking needs.

If you do not currently have a way to detect your dock, dock detection can be done easily using Apriltags and theisaac_ros_apriltagorROS image_procnodes to get started.

Use the Isaac ROS if using a Jetson platform to obtain a GPU optimized pipeline with your camera feeds.


key: chroma:document
string_value:
The defaults support this out of the box, seenova_carter_dockingfor an example.

## Dock Database

To dock your robot, you must provide the set of docks in your environment you’d like to utilize.

This is done in the docking server via theDock Databasewhich contains the set of docks, their instance types, and a set of shared plugins.

The plugins are separated from the dock instances so that many instances can share the same plugin to save on memory and networking overhead when potentially dozens or more docks exist in a space.

The docks plugins must be provided in your docking server’s configuration file.

However, the dock instance may be provided either in the configuration fileorwithin a provided filepath to decouple the server’s configuration from a particular application environment.


key: chroma:document
string_value:
The example below shows an inline configuration of the docking plugins and dock instances where one dock type (nova_carter_dock) is specified with 3 individual instances: a home dock, and 2 general shared fallback docks.

The docks can be specified as[x,y,theta]in any reference frame you like, as long as TF is aware of them.

Please update these with your own docking plugin and dock locations in your map.

The analog of this is shown below as an independentdock_database.yamlwhich can be provided to thedocking_servervia thedock_databaseparameter.

Note that you are required to provide at least 1 dock plugin and 1 dock instance.

The Docking Server’s Action API can take in a dock’s instance information separately to bypass the database, but its plugin must exist in the server’s configuration.

If you plan to only use this API, you can set adummy_dock.


key: chroma:document
string_value:
If you plan to only use this API, you can set adummy_dock.

Generally speaking, its wise to set your docks in the database and use the Docking Server’s API to dock at an instance’s Dock ID to decouple the semantic information about docks from the action request (requiring your application instead to have all of the docks’ locations), but bypassing the database can be useful for testing and movable docking targets.

The dock poses in the map can be annotated using your favorite map editing tools, obtained by/clicked_pointin rviz2, or measured location.

## Configuring Docking Server

Now that we have both a plugin for interacting with a dock and specified the locations of docks in your map, we’re ready to configure the docking server.

For this example, we’re going to use the Nvidia-Segway Nova Carter Robot and you can find the source code of this demo in thenova_carter_dockingpackage.

For a full list of parameters and their descriptions, check out theDocking Server.


key: chroma:document
string_value:
Below is an example configuration used by the Nova Carter robot.

Notable is the setting of thefixed_frametoodom, notmapin order to decouple localization error from the docking procedure.

We also use one dock pluginnova_carter_dockfor allNdocks specified in thedock_databasefile.

The simple charging dock plugin uses a 70cm staging offset from the dock’s database pose for staging.

This staging pose is selected as close enough to detect the dock but far enough away to give maneuvering space to account for expected dock movement or localization error.

Sinceuse_stall_detectionfor theJointStatesisfalse, we are considered successfully docked once we’re withindocking_threshold(5cm) to the docking pose.

This docking pose is specified as the detected pose with theexternal_detection_*offsets applied to account for the robot’s intended docking pose relative to the detected feature.


key: chroma:document
string_value:
In this example, Apriltags are used, so we apply the rotations to the Apriltag detected frame and a-0.18translational offset to account for the pose the robot should be in when docked relative to the tag’s pose.

Sinceuse_external_detection_poseanduse_battery_statusare both enabled, we use both detected dock poses (apriltag) and battery state information for determining if we’re charging.

The maximum speed is 15 cm/s to slowly and carefully back into the dock and we’ll retry docking 3x in case charging is not detected or we lose detected dock tracks during the attempt.

## Adding Docking Server to Launch

This server can now be added to your launch file with the path to this parameter file for use (or added to your main shared configuration file).

## Docking Action API

The API for docking and undocking is comparatively simple.

TheDockRobotaction consists of two main modalities: using the dock database or specifying a dock to use in the action.


key: chroma:document
string_value:
If using the database, setuse_dock_id=True(default) and you only need to specify thedock_idyou wish to use, such ashome_dock,flex_dock1, or whatever dock instance you like.

If bypassing the database,use_dock_idmust be set to false anddock_pose,dock_typemust be fully specified to make up for the lack of entry metadata in the database.

This requires the action caller to know about all of the docks, rather than pushing that into the Docking Server’s database, which is not recommended.

Optionally, you can disable using Nav2 to navigate to the staging pose if outside of the pre-staging tolerance usingnavigate_to_staging_pose=Falseor set the maximum time for staging navigationmax_staging_time.

In result, you obtain if the action was successful, if it wasn’t what the error code was, and the total number of retries attempted.


key: chroma:document
string_value:
During execution, feedback is provided on the current docking state - which is published irregularly only when an event occurs. It contains the state, the current total elapsed duration of attempted docking, and the current number of retries.

The feedback can be obtained from your action client if this information is useful to your application.

TheUndockRobotaction is even simpler. There are no required goal fields exceptdock_typeif undocking is being called when the server’s instance did not dock the robot to store its current state information (such as after a restart on the dock).

It contains no feedback and returns thesuccessstate and theerror_codeif a problem occurs.

## Putting It All Together

At this point, if you haven’t already, create your dock plugin (or useSimpleChargingDock), configuration file, and launch file - along with any other nodes required like apriltags or other detectors.


key: chroma:document
string_value:
You can see an example package used in this tutorial in thenova_carter_dockingpackage, which contains a configuration file and launch file containing the apriltags detector andPoseStampedpose publisher.

If you’re interested in using Apriltags and an Nvidia Jetson, you can find the tags we used in themedia/directory and the launch fileisaac_apriltag_detection_pipeline.launch.pywhich sets it all up for you.

If not using the Jetson, you can replace the Isaac ROS apriltag detector withimage_proc.

We can test this using the scriptdemo.pyinnova_carter_docking’s root directory.

It will set the robot’s pose as virtually the dock’s staging pose to bypass navigating to the staging pose and attempt docking immediately, then infinitely loop docking and undocking in a row.

This is a useful first-time setup to try docking, refine your detection offsets, and obtain reliability metrics of your complete system.

See the video below of this all at work!

Note that the robot is able to overcome:


key: chroma:document
string_value:
Note that the robot is able to overcome:

This script demonstrates the essential use of the Docking Server.

However, it does not use the dock database of pre-mapped dock locations that you setup.

After you launch Nav2 and localize your robot in your map, we can adjustdockRobot()to take in your desireddock_idand perform docking instead:

Then, we can see the full docking system in action in a non-trivial environment!

Depending on your robot’s relative pose to the dock and your pre-staging tolerance settings, Nav2 may attempt to navigate to the staging pose before docking.

If you wish to disable that, setgoal_msg.navigate_to_staging_pose=Falseand then Docking will trigger immediately.

You can see both of these in action in the video above.


