# embedding_metadata

key: chroma:document
string_value:
Interested in learning more? Take a look at the excellent paperNetwork Reconnaissance and Vulnerability Excavation of Secure DDS Systemsto understand why this matters.Display encrypted data packetsNow usetcpdumpto capture data packets:sudotcpdump-iany-Xudpportrange7401-7500A typical data packet looks like the following:21:18:14.531102 IP localhost.54869 > localhost.7415: UDP, length 328

0x0000:  4500 0164 bb42 4000 4011 8044 7f00 0001  E..d.B@.@..D....

0x0010:  7f00 0001 d655 1cf7 0150 ff63 5254 5053  .....U...P.cRTPS

0x0020:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J

0x0030:  3301 1400 0000 0003 492a 6066 8603 cdb5  3.......I*`f....

0x0040:  9df6 5da6 8402 2136 0c01 1400 0000 0000  ..]...!6........

0x0050:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J

...

0x0130:  7905 d390 3201 1400 3ae5 0b60 3906 967e  y...2...:..`9..~

0x0140:  5b17 fd42 de95 54b9 0000 0000 3401 1400  [..B..T.....4...

0x0150:  42ae f04d 0559 84c5 7116 1c51 91ba 3799  B..M.Y..q..Q..7.


key: chroma:document
string_value:
0x0160:  0000 0000                                ....The data in this RTPS packet is all encrypted.In addition to this data packet, you should see additional packets with node and enclave names; these support other ROS features such as parameters and services.

Encryption options for these packets can also be controlled by security policy.

Code Examples:

Language: unknown

sudoaptupdate

sudoaptinstalltcpdump

Language: unknown

# Disable ROS Security for both terminalsunsetROS_SECURITY_ENABLE# In terminal 1:ros2rundemo_nodes_cpptalker--ros-args--enclave/talker_listener/talker# In terminal 2:ros2rundemo_nodes_cpplistener--ros-args--enclave/talker_listener/listener

Language: unknown

sudotcpdump-X-ianyudpport7400

Language: unknown

20:18:04.400770 IP 8_xterm.46392 > 239.255.0.1.7400: UDP, length 252

0x0000:  4500 0118 d48b 4000 0111 7399 c0a8 8007  E.....@...s.....

0x0010:  efff 0001 b538 1ce8 0104 31c6 5254 5053  .....8....1.RTPS

...


key: chroma:document
string_value:
...

0x00c0:  5800 0400 3f0c 3f0c 6200 1c00 1800 0000  X...?.?.b.......

0x00d0:  2f74 616c 6b65 725f 6c69 7374 656e 6572  /talker_listener

0x00e0:  2f74 616c 6b65 7200 2c00 2800 2100 0000  /talker.,.(.!...

0x00f0:  656e 636c 6176 653d 2f74 616c 6b65 725f  enclave=/talker_

0x0100:  6c69 7374 656e 6572 2f74 616c 6b65 723b  listener/talker;

0x0110:  0000 0000 0100 0000                      ........

Language: unknown

sudotcpdump-iany-Xudpportrange7401-7500

Language: unknown

20:49:17.927303 IP localhost.46392 > localhost.7415: UDP, length 84

0x0000:  4500 0070 5b53 4000 4011 e127 7f00 0001  E..p[S@.@..'....

0x0010:  7f00 0001 b538 1cf7 005c fe6f 5254 5053  .....8...\.oRTPS

0x0020:  0203 010f 010f 4874 e752 0000 0100 0000  ......Ht.R......

0x0030:  0901 0800 cdee b760 5bf3 5aed 1505 3000  .......`[.Z...0.

0x0040:  0000 1000 0000 1204 0000 1203 0000 0000  ................

0x0050:  5708 0000 0001 0000 1200 0000 4865 6c6c  W...........Hell


key: chroma:document
string_value:
0x0060:  6f20 576f 726c 643a 2032 3133 3500 0000  o.World:.2135...

Language: unknown

# In terminal 1:exportROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystoreexportROS_SECURITY_ENABLE=trueexportROS_SECURITY_STRATEGY=Enforce

ros2rundemo_nodes_cpptalker--ros-args--enclave/talker_listener/talker# In terminal 2:exportROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystoreexportROS_SECURITY_ENABLE=trueexportROS_SECURITY_STRATEGY=Enforce

ros2rundemo_nodes_cpplistener--ros-args--enclave/talker_listener/listener

Language: unknown

sudotcpdump-X-ianyudpport7400

Language: unknown

21:09:07.336617 IP 8_xterm.60409 > 239.255.0.1.7400: UDP, length 596

0x0000:  4500 0270 c2f6 4000 0111 83d6 c0a8 8007  E..p..@.........

0x0010:  efff 0001 ebf9 1ce8 025c 331e 5254 5053  .........\3.RTPS

0x0020:  0203 010f bbdd 199c 7522 b6cb 699f 74ae  ........u"..i.t.

...

0x00c0:  5800 0400 3f0c ff0f 6200 2000 1a00 0000  X...?...b.......

0x00d0:  2f74 616c 6b65 725f 6c69 7374 656e 6572  /talker_listener


key: chroma:document
string_value:
0x00e0:  2f6c 6973 7465 6e65 7200 0000 2c00 2800  /listener...,.(.

0x00f0:  2300 0000 656e 636c 6176 653d 2f74 616c  #...enclave=/tal

0x0100:  6b65 725f 6c69 7374 656e 6572 2f6c 6973  ker_listener/lis

0x0110:  7465 6e65 723b 0000 0110 c400 1400 0000  tener;..........

0x0120:  4444 533a 4175 7468 3a50 4b49 2d44 483a  DDS:Auth:PKI-DH:

0x0130:  312e 3000 0400 0000 0c00 0000 6464 732e  1.0.........dds.

...

0x0230:  1100 0000 6464 732e 7065 726d 5f63 612e  ....dds.perm_ca.

0x0240:  616c 676f 0000 0000 0d00 0000 4543 4453  algo........ECDS

0x0250:  412d 5348 4132 3536 0000 0000 0000 0000  A-SHA256........

0x0260:  0510 0800 0700 0080 0600 0080 0100 0000  ................

Language: unknown

sudotcpdump-iany-Xudpportrange7401-7500

Language: unknown

21:18:14.531102 IP localhost.54869 > localhost.7415: UDP, length 328

0x0000:  4500 0164 bb42 4000 4011 8044 7f00 0001  E..d.B@.@..D....

0x0010:  7f00 0001 d655 1cf7 0150 ff63 5254 5053  .....U...P.cRTPS


key: chroma:document
string_value:
0x0020:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J

0x0030:  3301 1400 0000 0003 492a 6066 8603 cdb5  3.......I*`f....

0x0040:  9df6 5da6 8402 2136 0c01 1400 0000 0000  ..]...!6........

0x0050:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J

...

0x0130:  7905 d390 3201 1400 3ae5 0b60 3906 967e  y...2...:..`9..~

0x0140:  5b17 fd42 de95 54b9 0000 0000 3401 1400  [..B..T.....4...

0x0150:  42ae f04d 0559 84c5 7116 1c51 91ba 3799  B..M.Y..q..Q..7.

0x0160:  0000 0000                                ....


key: chroma:document
string_value:
Title: RHEL (RPM packages)

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

Install

RPMs.html

Section: Installation

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


key: chroma:document
string_value:
RHEL (RPM packages)Table of ContentsResourcesSystem setupSet localeEnable required repositoriesInstall development tools (optional)Install ROS 2Install additional RMW implementations (optional)Setup environmentTry some examplesNext stepsTroubleshootUninstallRPM packages for ROS 2 Jazzy Jalisco are currently available for RHEL 9. The target platforms are defined inREP 2000.ResourcesStatus Page:ROS 2 Jazzy (RHEL 9):amd64Jenkins InstanceRepositoriesSystem setupSet localeMake sure you have a locale which supportsUTF-8. If you are in a minimal environment (such as a docker container), the locale may be something minimal likeC. We test with the following settings. However, it should be fine if you’re using a different UTF-8 supported locale.locale# check for UTF-8sudodnfinstalllangpacks-englibc-langpack-enexportLANG=en_US.UTF-8


key: chroma:document
string_value:
locale# verify settingsEnable required repositoriesYou will need to enable the EPEL repositories and the PowerTools repository:sudodnfinstall'dnf-command(config-manager)'epel-release-y sudodnfconfig-manager--set-enabledcrbNoteThis step may be slightly different depending on the distribution you are using. Check the EPEL documentation:https://docs.fedoraproject.org/en-US/epel/#_quickstartNext, download the ROS 2 .repo file:sudodnfinstallcurl sudocurl--output/etc/yum.repos.d/ros2.repohttp://packages.ros.org/ros2/rhel/ros2.repoThen, update your metadata cache. DNF may prompt you to verify the GPG key, which should match the locationhttps://raw.githubusercontent.com/ros/rosdistro/master/ros.asc.sudodnfmakecacheInstall development tools (optional)If you are going to build ROS packages or otherwise do development, you can also install the development


key: chroma:document
string_value:
otherwise do development, you can also install the development tools:sudodnfinstall-y\cmake\gcc-c++\git\make\patch\python3-colcon-common-extensions\python3-mypy\python3-pip\python3-pydocstyle\python3-pytest\python3-pytest-repeat\python3-pytest-rerunfailures\python3-rosdep\python3-setuptools\python3-vcstool\wget# install some pip packages needed for testing and# not available as RPMspython3-mpipinstall-U--user\flake8-blind-except==0.1.1\flake8-class-newline\flake8-deprecatedInstall ROS 2ROS 2 packages are built on frequently updated RHEL systems. It is always recommended that you ensure your system is up to date before installing new packages.sudodnfupdateDesktop Install (Recommended): ROS, RViz, demos, tutorials.sudodnfinstallros-jazzy-desktopROS-Base Install (Bare Bones): Communication libraries, message packages, command line tools. No GUI tools.sudodnfinstallros-jazzy-ros-baseInstall additional RMW implementations (optional)The default middleware that ROS 2 uses isFastDDS, but the middleware (RMW) can


key: chroma:document
string_value:
that ROS 2 uses isFastDDS, but the middleware (RMW) can be replaced at runtime. See theguideon how to work with multiple RMWs.Setup environmentSet up your environment by sourcing the following file.# Replace ".bash" with your shell if you're not using bash# Possible values are: setup.bash, setup.sh, setup.zshsource/opt/ros/jazzy/setup.bashTry some examplesIf you installedros-jazzy-desktopabove you can try some examples.In one terminal, source the setup file and then run a C++talker:source/opt/ros/jazzy/setup.bash ros2rundemo_nodes_cpptalkerIn another terminal source the setup file and then run a Pythonlistener:source/opt/ros/jazzy/setup.bash ros2rundemo_nodes_pylistenerYou should see thetalkersaying that it’sPublishingmessages and thelistenersayingIheardthose messages. This verifies both the C++ and Python APIs are working properly. Hooray!Next stepsContinue with thetutorials and demosto configure your environment, create your own workspace and packages, and learn ROS 2 core


key: chroma:document
string_value:
create your own workspace and packages, and learn ROS 2 core concepts.TroubleshootTroubleshooting techniques can be foundhere.UninstallIf you need to uninstall ROS 2 or switch to a source-based install once you have already installed from binaries, run the following command:sudodnfremoveros-jazzy-*


key: chroma:document
string_value:
Code Examples:

Language: unknown

locale# check for UTF

8sudodnfinstalllangpacks

englibc

langpack

enexportLANG=en_US.UTF

8

locale# verify settings

Language: unknown

sudodnfinstall'dnf

command(config

manager)'epel

release

y

sudodnfconfig

manager-

set

enabledcrb

Language: unknown

sudodnfinstallcurl

sudocurl-

output/etc/yum.repos.d/ros2.repohttp://packages.ros.org/ros2/rhel/ros2.repo

Language: unknown

sudodnfmakecache

Language: unknown sudodnfinstall-y\cmake\gcc-c++\git\make\patch\python3-colcon-common-extensions\python3-mypy\python3-pip\python3-pydocstyle\python3-pytest\python3-pytest-repeat\python3-pytest-rerunfailures\python3-rosdep\python3-setuptools\python3-vcstool\wget# install some pip packages needed for testing and# not available as RPMspython3-mpipinstall-U--user\flake8-blind-except==0.1.1\flake8-class-newline\flake8-deprecated

Language: unknown

sudodnfupdate

Language: unknown

sudodnfinstallros

jazzy

desktop

Language: unknown

sudodnfinstallros

jazzy

ros

base


key: chroma:document
string_value:
Language: unknown

sudodnfinstallros

jazzy

ros

base

Language: unknown # Replace ".bash" with your shell if you're not using bash# Possible values are: setup.bash, setup.sh, setup.zshsource/opt/ros/jazzy/setup.bash

Language: unknown

source/opt/ros/jazzy/setup.bash

ros2rundemo_nodes_cpptalker

Language: unknown

source/opt/ros/jazzy/setup.bash

ros2rundemo_nodes_pylistener

Language: unknown

sudodnfremoveros

jazzy-*


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

The ROS 2 ProjectCheck out the resources below to learn more about the advancement of the ROS 2 project.ContributingFeatures StatusFeature IdeasRoadmapROSCon TalksProject GovernanceMarketingMetrics


key: chroma:document
string_value:
Title: Adding physical and collision properties URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Adding physical and collision propertiesGoal:Learn how to add collision and inertial properties to links, and how to add joint dynamics to joints.Tutorial level:IntermediateTime:10 minutesContentsCollisionPhysical PropertiesInertiaContact CoefficientsJoint DynamicsOther TagsNext StepsIn this tutorial, we’ll look at how to add some basic physical properties to your URDF model and how to specify its collision properties.CollisionSo far, we’ve only specified our links with a single sub-element,visual, which defines (not surprisingly) what the robot looks like. However, in order to get collision detection to work or to simulate the robot, we need to define acollisionelement as well.Here is the new urdfwith collision and physical properties.Here is the code for our new base link.<linkname="base_link"><visual><geometry><cylinderlength="0.6"radius="0.2"/></geometry><materialname="blue"><colorrgba="0 0 .8


key: chroma:document
string_value:
0 .8 1"/></material></visual><collision><geometry><cylinderlength="0.6"radius="0.2"/></geometry></collision></link>The collision element is a direct subelement of the link object, at the same level as the visual tag.The collision element defines its shape the same way the visual element does, with a geometry tag. The format for the geometry tag is exactly the same here as with the visual.You can also specify an origin in the same way as a subelement of the collision tag (as with the visual).In many cases, you’ll want the collision geometry and origin to be exactly the same as the visual geometry and origin. However, there are two main cases where you wouldn’t:Quicker Processing. Doing collision detection for two meshes is a lot more computational complex than for two simple geometries. Hence, you may want to replace the meshes with simpler geometries in the collision element.Safe Zones. You may want to restrict movement close to sensitive equipment. For instance, if we didn’t want anything to collide with


key: chroma:document
string_value:
For instance, if we didn’t want anything to collide with R2D2’s head, we might define the collision geometry to be a cylinder encasing his head to prevent anything from getting too close to his head.Physical PropertiesIn order to get your model to simulate properly, you need to define several physical properties of your robot, i.e. the properties that a physics engine like Gazebo would need.InertiaEvery link element being simulated needs an inertial tag. Here is a simple one.<linkname="base_link"><visual><geometry><cylinderlength="0.6"radius="0.2"/></geometry><materialname="blue"><colorrgba="0 0 .8 1"/></material></visual><collision><geometry><cylinderlength="0.6"radius="0.2"/></geometry></collision><inertial><massvalue="10"/><inertiaixx="1e-3"ixy="0.0"ixz="0.0"iyy="1e-3"iyz="0.0"izz="1e-3"/></inertial></link>This element is also a subelement of the link object.The mass is defined in kilograms.The 3x3 rotational inertia matrix is specified with the inertia element. Since this is symmetrical, it can be


key: chroma:document
string_value:
with the inertia element. Since this is symmetrical, it can be represented by only 6 elements, as such.ixxixyixzixyiyyiyzixziyzizzThis information can be provided to you by modeling programs such as MeshLab. The inertia of geometric primitives (cylinder, box, sphere) can be computed using Wikipedia’slist of moment of inertia tensors(and is used in the above example).The inertia tensor depends on both the mass and the distribution of mass of the object. A good first approximation is to assume equal distribution of mass in the volume of the object and compute the inertia tensor based on the object’s shape, as outlined above.If unsure what to put, a matrix with ixx/iyy/izz=1e-3 or smaller is often a reasonable default for a mid-sized link (it corresponds to a box of 0.1 m side length with a mass of 0.6 kg). The identity matrix is a particularly bad choice, since it is often much too high (it corresponds to a box of 0.1 m side length with a mass of 600 kg!).You can also specify an origin tag to specify the


key: chroma:document
string_value:
of 600 kg!).You can also specify an origin tag to specify the center of gravity and the inertial reference frame (relative to the link’s reference frame).When using realtime controllers, inertia elements of zero (or almost zero) can cause the robot model to collapse without warning, and all links will appear with their origins coinciding with the world origin.Contact CoefficientsYou can also define how the links behave when they are in contact with one another. This is done with a subelement of the collision tag called contact_coefficients. There are three attributes to specify:mu -Friction coefficientkp -Stiffness coefficientkd -Dampening coefficientJoint DynamicsHow the joint moves is defined by the dynamics tag for the joint. There are two attributes here:friction- The physical static friction. For prismatic joints, the units are Newtons. For revolving joints, the units are Newton meters.damping- The physical damping value. For prismatic joints, the units are Newton seconds per meter. For revolving


key: chroma:document
string_value:
joints, the units are Newton seconds per meter. For revolving joints, Newton meter seconds per radian.If not specified, these coefficients default to zero.Other TagsIn the realm of pure URDF (i.e. excluding Gazebo-specific tags), there are two remaining tags to help define the joints: calibration and safety controller. Check out thespec, as they are not included in this tutorial.Next StepsReduce the amount of code and annoying math you have to do byusing xacro.


key: chroma:document
string_value:
Code Examples:

Language: unknown

<linkname="base_link"><visual><geometry><cylinderlength="0.6"radius="0.2"/></geometry><materialname="blue"><colorrgba="0 0 .8 1"/></material></visual><collision><geometry><cylinderlength="0.6"radius="0.2"/></geometry></collision></link>

Language: unknown

<linkname="base_link"><visual><geometry><cylinderlength="0.6"radius="0.2"/></geometry><materialname="blue"><colorrgba="0 0 .8 1"/></material></visual><collision><geometry><cylinderlength="0.6"radius="0.2"/></geometry></collision><inertial><massvalue="10"/><inertiaixx="1e

3"ixy="0.0"ixz="0.0"iyy="1e

3"iyz="0.0"izz="1e

3"/></inertial></link>


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

URL: https://docs.ros.org/en/jazzy/Concepts/Advanced.html

Section: Installation

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

Advanced ConceptsThese conceptual documents are intended for developers who plan to modify or contribute to the ROS 2 core.The build systemInternal ROS 2 interfacesROS 2 middleware implementations


key: chroma:document
string_value:
Title: Synchronous vs. asynchronous service clients URL: https://docs.ros.org/en/jazzy/How-To-Guides/Sync-Vs-Async.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Synchronous vs. asynchronous service clientsLevel:IntermediateTime:10 minutesContentsIntroduction1 Synchronous calls1.1 Sync deadlock2 Asynchronous callsSummaryIntroductionThis guide is intended to warn users of the risks associated with the Python synchronous service clientcall()API. It is very easy to mistakenly cause deadlock when calling services synchronously, so we do not recommend usingcall().We provide an example on how to usecall()correctly for experienced users who wish to use synchronous calls and are aware of the pitfalls. We also highlight possible scenarios for deadlock that accompany it.Because we recommend avoiding sync calls, this guide will also address the features and usage of the recommended alternative, async calls (call_async()).The C++ service call API is only available in async, so the comparisons and examples in this guide pertain to Python services and clients. The definition of async given here generally applies to C++, with some exceptions.1 Synchronous callsA synchronous


key: chroma:document
string_value:
to C++, with some exceptions.1 Synchronous callsA synchronous client will block the calling thread when sending a request to a service until a response has been received; nothing else can happen on that thread during the call. The call can take arbitrary amounts of time to complete. Once complete, the response returns directly to the client.The following is an example of how to correctly execute a synchronous service call from a client node, similar to the async node in theSimple Service and Clienttutorial.importsysfromthreadingimportThreadfromexample_interfaces.srvimportAddTwoIntsimportrclpyfromrclpy.nodeimportNodeclassMinimalClientSync(Node):def__init__(self):super().__init__('minimal_client_sync')self.cli=self.create_client(AddTwoInts,'add_two_ints')whilenotself.cli.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')self.req=AddTwoInts.Request()defsend_request(self):self.req.a=int(sys.argv[1])self.req.b=int(sys.argv[2])returnself.cli.call(self.req)# This


key: chroma:document
string_value:
This only works because rclpy.spin() is called in a separate thread below.# Another configuration, like spinning later in main() or calling this method from a timer callback, would result in a deadlock.defmain():rclpy.init()minimal_client=MinimalClientSync()spin_thread=Thread(target=rclpy.spin,args=(minimal_client,))spin_thread.start()response=minimal_client.send_request()minimal_client.get_logger().info('Result of add_two_ints: for%d+%d=%d'%(minimal_client.req.a,minimal_client.req.b,response.sum))minimal_client.destroy_node()rclpy.shutdown()if__name__=='__main__':main()Note insidemain()that the client callsrclpy.spinin a separate thread. Bothsend_requestandrclpy.spinare blocking, so they need to be on separate threads.1.1 Sync deadlockThere are several ways that the synchronouscall()API can cause deadlock.As mentioned in the comments of the example above, failing to create a separate thread to spinrclpyis one cause of deadlock. When a client is blocking a thread waiting for a response, but the response can


key: chroma:document
string_value:
blocking a thread waiting for a response, but the response can only be returned on that same thread, the client will never stop waiting, and nothing else can happen.Another cause of deadlock is blockingrclpy.spinby calling a service synchronously in a subscription, timer callback or service callback. For example, if the synchronous client’ssend_requestis placed in a callback:deftrigger_request(msg):response=minimal_client.send_request()# This will cause deadlockminimal_client.get_logger().info('Result of add_two_ints: for%d+%d=%d'%(minimal_client.req.a,minimal_client.req.b,response.sum))subscription=minimal_client.create_subscription(String,'trigger',trigger_request,10)rclpy.spin(minimal_client)Deadlock occurs becauserclpy.spinwill not preempt the callback with thesend_requestcall. In general, callbacks should only perform light and fast operations.WarningWhen deadlock occurs, you will not receive any indication that the service is blocked. There will be no warning or exception thrown, no indication in the


key: chroma:document
string_value:
will be no warning or exception thrown, no indication in the stack trace, and the call will not fail.2 Asynchronous callsAsync calls inrclpyare entirely safe and the recommended method of calling services. They can be made from anywhere without running the risk of blocking other ROS and non-ROS processes, unlike sync calls.An asynchronous client will immediately returnfuture, a value that indicates whether the call and response is finished (not the value of the response itself), after sending a request to a service. The returnedfuturemay be queried for a response at any time.Since sending a request doesn’t block anything, a loop can be used to both spinrclpyand checkfuturein the same thread, for example:whilerclpy.ok():rclpy.spin_once(node)iffuture.done():#Get responseTheSimple Service and Clienttutorial for Python illustrates how to perform an async service call and retrieve thefutureusing a loop.Thefuturecan also be retrieved using a timer or callback, like inthis example, a dedicated thread, or by


key: chroma:document
string_value:
or callback, like inthis example, a dedicated thread, or by another method. It is up to you, as the caller, to decide how to storefuture, check on its status, and retrieve your response.SummaryIt is not recommended to implement a synchronous service client. They are susceptible to deadlock, but will not provide any indication of issue when deadlock occurs. If you must use synchronous calls, the example in section1 Synchronous callsis a safe method of doing so. You should also be aware of the conditions that cause deadlock outlined in section1.1 Sync deadlock. We recommend using async service clients instead.


key: chroma:document
string_value:
Language: unknown importsysfromthreadingimportThreadfromexample_interfaces.srvimportAddTwoIntsimportrclpyfromrclpy.nodeimportNodeclassMinimalClientSync(Node):def__init__(self):super().__init__('minimal_client_sync')self.cli=self.create_client(AddTwoInts,'add_two_ints')whilenotself.cli.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')self.req=AddTwoInts.Request()defsend_request(self):self.req.a=int(sys.argv[1])self.req.b=int(sys.argv[2])returnself.cli.call(self.req)# This only works because rclpy.spin() is called in a separate thread below.# Another configuration, like spinning later in main() or calling this method from a timer callback, would result in a deadlock.defmain():rclpy.init()minimal_client=MinimalClientSync()spin_thread=Thread(target=rclpy.spin,args=(minimal_client,))spin_thread.start()response=minimal_client.send_request()minimal_client.get_logger().info('Result of add_two_ints:


key: chroma:document
string_value:
of add_two_ints: for%d+%d=%d'%(minimal_client.req.a,minimal_client.req.b,response.sum))minimal_client.destroy_node()rclpy.shutdown()if__name__=='__main__':main()


key: chroma:document
string_value:
Language: unknown deftrigger_request(msg):response=minimal_client.send_request()# This will cause deadlockminimal_client.get_logger().info('Result of add_two_ints: for%d+%d=%d'%(minimal_client.req.a,minimal_client.req.b,response.sum))subscription=minimal_client.create_subscription(String,'trigger',trigger_request,10)rclpy.spin(minimal_client)

Language: unknown

whilerclpy.ok():rclpy.spin_once(node)iffuture.done():#Get response


key: chroma:document
string_value:
Title: Experimenting with a dummy robot URL: https://docs.ros.org/en/jazzy/Tutorials/Demos/dummy-robot-demo.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Experimenting with a dummy robotIn this demo, we present a simple demo robot with all components from publishing joint states over publishing fake laser data until visualizing the robot model on a map in RViz.Launching the demoWe assume your ROS 2 installation dir as~/ros2_ws. Please change the directories according to your platform.To start the demo, we execute the demo bringup launch file, which we are going to explain in more details in the next section.Source Builddeb Packagemkdir -p ~/ros2_ws/src cd ~/ros2_ws/src git clone -b ${ROS_DISTRO}https://github.com/ros2/demoscd .. && colcon build –packages-up-to dummy_robot_bringup source ~/ros2_ws/install/setup.bash ros2 launch dummy_robot_bringup dummy_robot_bringup_launch.pysudo apt install ros-${ROS_DISTRO}-dummy-robot-bringup ros2 launch dummy_robot_bringup dummy_robot_bringup_launch.pyYou should see some prints inside your terminal along the lines of the


key: chroma:document
string_value:
see some prints inside your terminal along the lines of the following:[INFO][launch]:DefaultloggingverbosityissettoINFO[INFO][dummy_map_server-1]:processstartedwithpid[2922][INFO][robot_state_publisher-2]:processstartedwithpid[2923][INFO][dummy_joint_states-3]:processstartedwithpid[2924][INFO][dummy_laser-4]:processstartedwithpid[2925][dummy_laser-4][INFO][1714837459.645517297][dummy_laser]:angleinc:0.004363[dummy_laser-4][INFO][1714837459.645613393][dummy_laser]:scansize:1081[dummy_laser-4][INFO][1714837459.645626640][dummy_laser]:scantimeincrement:0.000000[robot_state_publisher-2][INFO][1714837459.652977937][robot_state_publisher]:RobotinitializedIf you now open RViz2 in a new terminal, you’ll see your robot. 🎉$source~/ros2_ws/install/setup.bash $rviz2This opens RViz2. Assuming you have your dummy_robot_bringup still launched, you can now add the TF display plugin and configure your global frame toworld. Once you did that, you should see a similar picture:What’s happening?If you have a closer look at the


key: chroma:document
string_value:
picture:What’s happening?If you have a closer look at the launch file, we start a couple of nodes at the same time.dummy_map_serverdummy_laserdummy_joint_statesrobot_state_publisherThe first two packages are relatively simple. Thedummy_map_serverconstantly publishes an empty map with a periodic update. Thedummy_laserdoes basically the same; publishing dummy fake laser scans.Thedummy_joint_statesnode is publishing fake joint state data. As we are publishing a simple RRbot with only two joints, this node publishes joint states values for these two joints.Therobot_state_publisheris doing the actual interesting work. It parses the given URDF file, extracts the robot model and listens to the incoming joint states. With this information, it publishes TF values for our robot which we visualize in RViz.Hooray!


key: chroma:document
string_value:
Code Examples:

Language: unknown

[INFO][launch]:DefaultloggingverbosityissettoINFO[INFO][dummy_map_server

1]:processstartedwithpid[2922][INFO][robot_state_publisher

2]:processstartedwithpid[2923][INFO][dummy_joint_states

3]:processstartedwithpid[2924][INFO][dummy_laser

4]:processstartedwithpid[2925][dummy_laser

4][INFO][1714837459.645517297][dummy_laser]:angleinc:0.004363[dummy_laser

4][INFO][1714837459.645613393][dummy_laser]:scansize:1081[dummy_laser

4][INFO][1714837459.645626640][dummy_laser]:scantimeincrement:0.000000[robot_state_publisher

2][INFO][1714837459.652977937][robot_state_publisher]:Robotinitialized

Language: unknown

$source~/ros2_ws/install/setup.bash

$rviz2


key: chroma:document
string_value:
Title: macOS (source)

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

Development

Setup.html

Section: Installation

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


key: chroma:document
string_value:
macOS (source)Table of ContentsSystem requirementsSystem setupInstall prerequisitesDisable System Integrity Protection (SIP)Build ROS 2Get ROS 2 codeInstall additional RMW implementations (optional)Build the code in the workspaceSetup environmentTry some examplesNext stepsUse the ROS 1 bridge (optional)Stay up to dateTroubleshootUninstallSystem requirementsWe currently support macOS Mojave (10.14).System setupInstall prerequisitesYou need the following things installed to build ROS 2:XcodeIf you don’t already have it installed, install [Xcode](https://apps.apple.com/app/xcode/id497799835).Note: Versions of Xcode later than 11.3.1 can no longer be installed on macOS Mojave, so you will need to install an older version manually, see:https://stackoverflow.com/a/61046761Also, if you don’t already have it installed, install the Command Line Tools:xcode-select--install# This command will not succeed if you have not installed Xcode.appsudoxcode-select--switch/Applications/Xcode.app/Contents/Developer# If you


key: chroma:document
string_value:
If you installed Xcode.app manually, you need to either open it or run:sudoxcodebuild-license# To accept the Xcode.app licensebrew(needed to install more stuff; you probably already have this):Follow installation instructions athttp://brew.sh/Optional: Check thatbrewis happy with your system configuration by running:brewdoctorFix any problems that it identifies.Usebrewto install more stuff:brewinstallasioassimpbisonbulletcmakeconsole_bridgecppcheck\cuniteigenfreetypegraphvizopencvopensslorocos-kdlpcrepoco\pyqt@5pythonqt@5sipspdlogtinyxml2Setup some environment variables:# Add the openssl dir for DDS-Security# if you are using BASH, then replace '.zshrc' with '.bashrc'echo"export OPENSSL_ROOT_DIR=$(brew--prefixopenssl)">>~/.zshrc# Add the Qt directory to the PATH and CMAKE_PREFIX_PATHexportCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:$(brew--prefixqt@5)exportPATH=$PATH:$(brew--prefixqt@5)/binUsepython3-mpip(justpipmay install Python3 or Python2) to install more stuff:python3-mpipinstall--upgradepip


key: chroma:document
string_value:
python3-mpipinstall-U\--config-settings="--global-option=build_ext"\--config-settings="--global-option=-I$(brew--prefixgraphviz)/include/"\--config-settings="--global-option=-L$(brew--prefixgraphviz)/lib/"\argcompletecatkin_pkgcolcon-common-extensionscoverage\cryptographyempyflake8flake8-blind-except==0.1.1flake8-builtins\flake8-class-newlineflake8-comprehensionsflake8-deprecated\flake8-docstringsflake8-import-orderflake8-quotes\importlib-metadatajsonschemalark==1.1.1lxmlmatplotlibmockmypy==0.931netifaces\nosepep8psutilpydocstylepydotpygraphvizpyparsing==2.4.7\pytest-mockrosdeprosdistrosetuptools==59.6.0vcstoolPlease ensure that the$PATHenvironment variable contains the install location of the binaries ($(brew--prefix)/bin)Optional: if you want to build the ROS 1<->2 bridge, then you must also install ROS 1:Start with the normal install instructions:http://wiki.ros.org/kinetic/Installation/OSX/Homebrew/SourceWhen you get to the step where you callrosinstall_generatorto get the source code, here’s an


key: chroma:document
string_value:
you callrosinstall_generatorto get the source code, here’s an alternate invocation that brings in just the minimum required to produce a useful bridge:rosinstall_generatorcatkincommon_msgsroscpprosmsg--rosdistrokinetic--deps--wet-only--tar>kinetic-ros2-bridge-deps.rosinstall wstoolinit-j8srckinetic-ros2-bridge-deps.rosinstallOtherwise, just follow the normal instructions, then source the resultinginstall_isolated/setup.bashbefore proceeding here to build ROS 2.Disable System Integrity Protection (SIP)macOS/OS X versions >=10.11 have System Integrity Protection enabled by default. So that SIP doesn’t prevent processes from inheriting dynamic linker environment variables, such asDYLD_LIBRARY_PATH, you’ll need to disable itfollowing these instructions.Build ROS 2Get ROS 2 codeCreate a workspace and clone all repos:mkdir-p~/ros2_jazzy/srccd~/ros2_jazzy vcsimport--inputhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repossrcInstall additional RMW implementations (optional)The default middleware that


key: chroma:document
string_value:
RMW implementations (optional)The default middleware that ROS 2 uses isFastDDS, but the middleware (RMW) can be replaced at build or runtime. See theguideon how to work with multiple RMWs.Build the code in the workspaceRun thecolcontool to build everything (more on usingcolconinthis tutorial):cd~/ros2_jazzy/ colconbuild--symlink-install--packages-skip-by-deppython_qt_bindingNote: due to an unresolved issue with SIP, Qt@5, and PyQt5, we need to disablepython_qt_bindingto have the build succeed. This will be removed when the issue is resolved, see:https://github.com/ros-visualization/python_qt_binding/issues/103Setup environmentSource the ROS 2 setup file:.~/ros2_jazzy/install/setup.zshThis will automatically set up the environment for any DDS vendors that support was built for.Try some examplesIn one terminal, set up the ROS 2 environment as described above and then run a C++talker:ros2rundemo_nodes_cpptalkerIn another terminal source the setup file and then run a


key: chroma:document
string_value:
another terminal source the setup file and then run a Pythonlistener:ros2rundemo_nodes_pylistenerYou should see thetalkersaying that it’sPublishingmessages and thelistenersayingIheardthose messages. This verifies both the C++ and Python APIs are working properly. Hooray!Next stepsContinue with thetutorials and demosto configure your environment, create your own workspace and packages, and learn ROS 2 core concepts.Use the ROS 1 bridge (optional)The ROS 1 bridge can connect topics from ROS 1 to ROS 2 and vice-versa. See the dedicateddocumentationon how to build and use the ROS 1 bridge.Stay up to dateSeeMaintain source checkoutto periodically refresh your source installation.TroubleshootTroubleshooting techniques can be foundhere.UninstallIf you installed your workspace with colcon as instructed above, “uninstalling” could be just a matter of opening a new terminal and not sourcing the workspace’ssetupfile. This way, your environment will behave as though there is no Jazzy install on your system.If


key: chroma:document
string_value:
behave as though there is no Jazzy install on your system.If you’re also trying to free up space, you can delete the entire workspace directory with:rm-rf~/ros2_jazzy


key: chroma:document
string_value:
Code Examples:

Language: unknown xcode-select--install# This command will not succeed if you have not installed Xcode.appsudoxcode-select--switch/Applications/Xcode.app/Contents/Developer# If you installed Xcode.app manually, you need to either open it or run:sudoxcodebuild-license# To accept the Xcode.app license

Language: unknown

brewdoctor

Language: unknown

brewinstallasioassimpbisonbulletcmakeconsole_bridgecppcheck\cuniteigenfreetypegraphvizopencvopensslorocos

kdlpcrepoco\pyqt@5pythonqt@5sipspdlogtinyxml2

Language: unknown # Add the openssl dir for DDS-Security# if you are using BASH, then replace '.zshrc' with '.bashrc'echo"export OPENSSL_ROOT_DIR=$(brew--prefixopenssl)">>~/.zshrc# Add the Qt directory to the PATH and CMAKE_PREFIX_PATHexportCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:$(brew--prefixqt@5)exportPATH=$PATH:$(brew--prefixqt@5)/bin

Language: unknown

python3

mpipinstall-

upgradepip

python3

mpipinstall

U\-

config

settings="-

global

option=build_ext"\-

config

settings="-

global


key: chroma:document
string_value:
global

option=build_ext"\-

config

settings="-

global

option=

I$(brew-

prefixgraphviz)/include/"\-

config

settings="-

global

option=

L$(brew-

prefixgraphviz)/lib/"\argcompletecatkin_pkgcolcon

common

extensionscoverage\cryptographyempyflake8flake8

blind

except==0.1.1flake8

builtins\flake8

class

newlineflake8

comprehensionsflake8

deprecated\flake8

docstringsflake8

import

orderflake8

quotes\importlib

metadatajsonschemalark==1.1.1lxmlmatplotlibmockmypy==0.931netifaces\nosepep8psutilpydocstylepydotpygraphvizpyparsing==2.4.7\pytest

mockrosdeprosdistrosetuptools==59.6.0vcstool

Language: unknown

rosinstall_generatorcatkincommon_msgsroscpprosmsg-

rosdistrokinetic-

deps-

wet

only-

tar>kinetic

ros2

bridge

deps.rosinstall

wstoolinit

j8srckinetic

ros2

bridge

deps.rosinstall

Language: unknown

mkdir

p~/ros2_jazzy/srccd~/ros2_jazzy

vcsimport-

inputhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repossrc

Language: unknown

cd~/ros2_jazzy/

colconbuild-

symlink


key: chroma:document
string_value:
Language: unknown

cd~/ros2_jazzy/

colconbuild-

symlink

install-

packages

skip

by

deppython_qt_binding

Language: unknown

.~/ros2_jazzy/install/setup.zsh

Language: unknown

ros2rundemo_nodes_cpptalker

Language: unknown

ros2rundemo_nodes_pylistener

Language: unknown

rm

rf~/ros2_jazzy


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


key: chroma:document
string_value:
Title: Using Fast DDS Discovery Server as discovery protocol [community-contributed] URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Discovery-Server/Discovery-Server.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Using Fast DDS Discovery Server as discovery protocol [community-contributed]Goal:This tutorial will show how to launch ROS 2 Nodes using theFast DDS Discovery Serverdiscovery protocol.Tutorial level:AdvancedTime:20 minutesTable of ContentsBackgroundFast DDS Discovery Server v2PrerequisitesRun this tutorialSetup Discovery ServerLaunch listener nodeLaunch talker nodeDemonstrate Discovery Server executionVisualization toolrqt_graphAdvance use casesServer RedundancyBackup ServerDiscovery partitionsROS 2 IntrospectionDaemon’s related toolsNo Daemon toolsCompare Fast DDS Discovery Server with Simple Discovery ProtocolBackgroundStarting from ROS 2 Eloquent Elusor, theFast DDS Discovery Serverprotocol is a feature that offers a centralized dynamic discovery mechanism, as opposed to the distributed mechanism used in DDS by default. This tutorial explains how to run some ROS 2 examples using the Fast DDS Discovery Server feature as discovery communication.In order to get more information about the available


key: chroma:document
string_value:
order to get more information about the available discovery configuration, please check thefollowing documentationor read theFast DDS Discovery Server specific documentation.TheSimple Discovery Protocolis the standard protocol defined in theDDS standard. However, it has known disadvantages in some scenarios.It does notScaleefficiently, as the number of exchanged packets increases significantly as new nodes are added.It requiresmulticastingcapabilities that may not work reliably in some scenarios, e.g. WiFi.TheFast DDS Discovery Serverprovides a Client-Server Architecture that allows nodes to connect with each other using an intermediate server. Each node functions as adiscovery client, sharing its info with one or morediscovery serversand receiving discovery information from it. This reduces discovery-related network traffic and it does not require multicasting capabilities.These discovery servers can be independent, duplicated or connected with each other in order to create redundancy over the network and


key: chroma:document
string_value:
each other in order to create redundancy over the network and avoid having a single point of failure.Fast DDS Discovery Server v2The latest ROS 2 Foxy Fitzroy release (December 2020) included a new version, version 2 of the Fast DDS Discovery Server. This version includes a new filter feature that further reduces the number of discovery messages sent. This version uses the topic of the different nodes to decide if two nodes wish to communicate, or if they can be left unmatched (i.e. not discovering each other). The following figure shows the decrease in discovery messages:This architecture reduces the number of messages sent between the server and clients dramatically. In the following graph, the reduction in network traffic over the discovery phase for theRMF Clinic demonstrationis shown:In order to use this functionality, the discovery server can be configured using theXML configuration for Participants. It is also possible to configure the discovery server using thefastddstooland anenvironment variable,


key: chroma:document
string_value:
server using thefastddstooland anenvironment variable, which is the approach used in this tutorial. For a more detailed explanation about the configuration of the discovery server, visitthe Fast DDS Discovery Server documentation.PrerequisitesThis tutorial assumes you have a ROS 2 Foxy (or newer)installation. If your installation is using a ROS 2 version lower than Foxy, you cannot use thefastddstool. Thus, in order to use the Discovery Server, you can update your repository to use a different Fast DDS version, or configure the discovery server using theFast DDS XML QoS configuration.Run this tutorialThetalker-listenerROS 2 demo creates atalkernode that publishes a “hello world” message every second, and alistenernode that listens to these messages.Bysourcing ROS 2you will get access to the CLI toolfastdds. This tool gives access to thediscovery tool, which can be used to launch a discovery server. This server will manage the discovery process for the nodes that connect to it.ImportantDo not forget


key: chroma:document
string_value:
process for the nodes that connect to it.ImportantDo not forget tosource ROS 2in every new terminal opened.Setup Discovery ServerStart by launching a discovery server with id 0, port 11811 (default port) and listening on all available interfaces.Open a new terminal and run:fastdds discovery --server-id 0Launch listener nodeExecute the listener demo, to listen to the/chattertopic.In a new terminal, set the environment variableROS_DISCOVERY_SERVERto the location of the discovery server. (Do not forget to source ROS 2 in every new terminal)LinuxWindowsexport ROS_DISCOVERY_SERVER=127.0.0.1:11811set ROS_DISCOVERY_SERVER=127.0.0.1:11811Launch the listener node. Use the argument--remap__node:=listener_discovery_serverto change the node’s name for this tutorial.ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_discovery_serverThis will create a ROS 2 node, that will automatically create a client for the discovery server and connect to the server created previously to perform discovery, rather


key: chroma:document
string_value:
to the server created previously to perform discovery, rather than using multicast.Launch talker nodeOpen a new terminal and set theROS_DISCOVERY_SERVERenvironment variable as before so that the node starts a discovery client.LinuxWindowsexport ROS_DISCOVERY_SERVER=127.0.0.1:11811set ROS_DISCOVERY_SERVER=127.0.0.1:11811ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_discovery_serverYou should now see the talker publishing “hello world” messages, and the listener receiving these messages.Demonstrate Discovery Server executionSo far, there is no evidence that this example and the standard talker-listener example are running differently. To clearly demonstrate this, run another node that is not connected to the discovery server. Run a new listener (listening in/chattertopic by default) in a new terminal and check that it is not connected to the talker already running.ros2 run demo_nodes_cpp listener --ros-args --remap __node:=simple_listenerThe new listener node should not be receiving the


key: chroma:document
string_value:
new listener node should not be receiving the “hello world” messages.To finally verify that everything is running correctly, a new talker can be created using the simple discovery protocol (the default DDS distributed discovery mechanism) for discovery.ros2 run demo_nodes_cpp talker --ros-args --remap __node:=simple_talkerNow you should see thesimple_listenernode receiving the “hello world” messages fromsimple_talkerbut not the other messages fromtalker_discovery_server.Visualization toolrqt_graphTherqt_graphtool can be used to verify the nodes and structure of this example. Remember, in order to userqt_graphwith the discovery server protocol (i.e., to see thelistener_discovery_serverandtalker_discovery_servernodes) theROS_DISCOVERY_SERVERenvironment variable must be set before launching it.Advance use casesThe following sections show different features of the discovery server that allow you to build a robust discovery server over the network.Server RedundancyBy usingfastddstool, multiple discovery


key: chroma:document
string_value:
RedundancyBy usingfastddstool, multiple discovery servers can be created. Discovery clients (ROS nodes) can connect to as many servers as desired. This allows to have a redundant network that will work even if some servers or nodes shut down unexpectedly. The figure below shows a simple architecture that provides server redundancy.In several terminals, run the following code to establish a communication with redundant servers.fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888--server-idNmeans server with id N. When referencing the servers withROS_DISCOVERY_SERVER, server0must be in first place and server1in second place.LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talkerLinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"set


key: chroma:document
string_value:
ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listenerNow, if one of these servers fails, there will still be discovery capability available and nodes will still discover each other.Backup ServerThe Fast DDS Discovery Server allows creating a server with backup functionality. This allows the server to restore the last state it saved in case of a shutdown.In different terminals, run the following code to establish a communication with a backed-up server.fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811 --backupLinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talkerLinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listenerSeveral backup files are created


key: chroma:document
string_value:
--remap __node:=listenerSeveral backup files are created in the discovery server’s working directory (the directory it was launched in). The twoSQLitefiles and twojsonfiles contain the information required to start a new server and restore the failed server’s state in case of failure, avoiding the need for the discovery process to happen again, and without losing information.Discovery partitionsCommunication with discovery servers can be split to create virtual partitions in the discovery information. This means that two endpoints will only know about each other if there is a shared discovery server or a network of discovery servers between them. We are going to execute an example with two independent servers. The following figure shows the architecture.With this schemaListener1will be connected toTalker1andTalker2, as they shareServer1.Listener2will connect withTalker1as they shareServer2. ButListener2will not hear the messages fromTalker2because they do not share any discovery server or discovery servers,


key: chroma:document
string_value:
they do not share any discovery server or discovery servers, including indirectly via connections between redundant discovery servers.Run the first server listening on localhost with the default port of 11811.fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811In another terminal run the second server listening on localhost using another port, in this case port 11888.fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888Now, run each node in a different terminal. UseROS_DISCOVERY_SERVERenvironment variable to decide which server they are connected to. Be aware that theids must match.LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_1LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"ros2 run demo_nodes_cpp listener --ros-args --remap


key: chroma:document
string_value:
run demo_nodes_cpp listener --ros-args --remap __node:=listener_1LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_2LinuxWindowsexport ROS_DISCOVERY_SERVER=";127.0.0.1:11888"set ROS_DISCOVERY_SERVER=";127.0.0.1:11888"ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_2We should see howListener1is receiving messages from both talker nodes, whileListener2is in a different partition fromTalker2and so does not receive messages from it.NoteOnce two endpoints (ROS nodes) have discovered each other, they do not need the discovery server network between them to listen to each other’s messages.ROS 2 IntrospectionTheROS 2 Command Line Interfacesupports several introspection tools to analyze the behavior of a ROS 2 network. These tools (i.e.ros2bagrecord,ros2topiclist, etc.) are very helpful to understand a ROS 2 working network.Most of these tools use DDS simple discovery to exchange


key: chroma:document
string_value:
of these tools use DDS simple discovery to exchange topic information with every existing participant (using simple discovery, every participant in the network is connected with each other). However, the new Discovery Server v2 implements a network traffic reduction scheme that limits the discovery data between participants that do not share a topic. This means that nodes will only receive topic’s discovery data if it has a writer or a reader for that topic. As most ROS 2 CLIs need a node in the network (some of them rely on a running ROS 2 daemon, and some create their own nodes), using the Discovery Server v2 these nodes will not have all the network information, and thus their functionality will be limited.The Discovery Server v2 functionality allows every Participant to run as aSuper Client, a kind ofClientthat connects to aServer, from which it receives all the available discovery information (instead of just what it needs). In this sense, ROS 2 introspection tools can be configured asSuper Client, thus


key: chroma:document
string_value:
2 introspection tools can be configured asSuper Client, thus being able to discover every entity that is using the Discovery Server protocol within the network.NoteIn this section we use the termParticipantas a DDS entity. Each DDSParticipantcorresponds with a ROS 2Context, a ROS 2 abstraction over DDS.Nodesare ROS 2 entities that rely on DDS communication interfaces:DataWriterandDataReader. EachParticipantcan hold multiple ROS 2 Nodes. For further details about these concepts, please visit theNode to Participant mapping design documentDaemon’s related toolsThe ROS 2 Daemon is used in several ROS 2 CLI introspection tools. It creates its own Participant to add a ROS 2 Node to the network graph, in order to receive all the data sent. In order for the ROS 2 CLI to work when using Discovery Server mechanism, the ROS 2 Daemon needs to be configured asSuper Client. Therefore, this section is devoted to explain how to use ROS 2 CLI with ROS 2 Daemon running as aSuper Client. This will allow the Daemon to discover


key: chroma:document
string_value:
as aSuper Client. This will allow the Daemon to discover the entire Node graph, and to receive all topic and endpoint information. To do so, a Fast DDS XML configuration file is used to configure the ROS 2 Daemon and CLI tools.Below you can find a XML configuration profile, which for this tutorial should be saved in the working directory as`super_client_configuration_file.xml`file. This file will configure every new participant using it, as aSuper Client.<?xml version="1.0" encoding="UTF-8"


key: chroma:document
string_value:
using it, as aSuper Client.<?xml version="1.0" encoding="UTF-8" ?><dds><profilesxmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles"><participantprofile_name="super_client_profile"is_default_profile="true"><rtps><builtin><discovery_config><discoveryProtocol>SUPER_CLIENT</discoveryProtocol><discoveryServersList><RemoteServerprefix="44.53.00.5f.45.50.52.4f.53.49.4d.41"><metatrafficUnicastLocatorList><locator><udpv4><address>127.0.0.1</address><port>11811</port></udpv4></locator></metatrafficUnicastLocatorList></RemoteServer></discoveryServersList></discovery_config></builtin></rtps></participant></profiles></dds>NoteUnder theRemoteServertag, theprefixattribute value should be updated according to the server ID passed on the CLI (seeFast DDS CLI). The value specified in the shown XML snippet corresponds to an ID of value 0.First of all, instantiate a Discovery Server usingFast DDS CLIspecifying an ID of value 0.fastdds discovery -i 0 -l 127.0.0.1 -p 11811Run a talker and a listener that will discover


key: chroma:document
string_value:
-p 11811Run a talker and a listener that will discover each other through the Server (notice thatROS_DISCOVERY_SERVERconfiguration is the same as the one insuper_client_configuration_file.xml).LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listenerLinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talkerThen, instantiate a ROS 2 Daemon using theSuper Clientconfiguration (remember to source ROS 2 installation in every new terminal).LinuxWindowsexport FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlset FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlros2 daemon stopros2 daemon startros2 topic listros2 node info /talkerros2 topic info /chatterros2 topic echo /chatterWe can also see the Node’s Graph using the ROS 2 toolrqt_graphas follows (you may need to press


key: chroma:document
string_value:
using the ROS 2 toolrqt_graphas follows (you may need to press the refresh button):LinuxWindowsexport FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlset FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlrqt_graphNo Daemon toolsSome ROS 2 CLI tools do not use the ROS 2 Daemon. In order for these tools to connect with a Discovery Server and receive all the topics information they need to be instantiated as aSuper Clientthat connects to theServer.Following the previous configuration, build a simple system with a talker and a listener. First, run aServer:fastdds discovery -i 0 -l 127.0.0.1 -p 11811Then, run the talker and listener in separate terminals:LinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listenerLinuxWindowsexport ROS_DISCOVERY_SERVER="127.0.0.1:11811"set ROS_DISCOVERY_SERVER="127.0.0.1:11811"ros2 run demo_nodes_cpp talker --ros-args --remap


key: chroma:document
string_value:
run demo_nodes_cpp talker --ros-args --remap __node:=talkerContinue using the ROS 2 CLI with--no-daemonoption with the new configuration. New nodes will connect with the existing Server and will know every topic. ExportingROS_DISCOVERY_SERVERis not needed as the ROS 2 tools will be configured through theFASTRTPS_DEFAULT_PROFILES_FILE.LinuxWindowsexport FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlset FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xmlros2 topic list --no-daemonros2 node info /talker --no-daemon --spin-time 2Compare Fast DDS Discovery Server with Simple Discovery ProtocolIn order to compare executing nodes using theSimple DiscoveryProtocol (the default DDS mechanism for distributed discovery) or theDiscovery Server, two scripts that execute a talker and many listeners and analyze the network traffic during this time are provided. For this experiment,tsharkis required to be installed on your system. The configuration file is mandatory in order to avoid


key: chroma:document
string_value:
system. The configuration file is mandatory in order to avoid using intraprocess mode.NoteThese scripts are only supported on Linux, and require a discovery server closure feature that is only available from versions newer than the version provided in ROS 2 Foxy. In order to use this functionality, compile ROS 2 with Fast DDS v2.1.0 or higher.These scripts’ features are references for advanced purposes and their study is left to the user.bashnetworktrafficgeneratorpython3graphgeneratorXMLconfigurationRun the bash script with the path tosetup.bashfile to source ROS 2 as an argument. This will generate the traffic trace for simple discovery. Execute the same script with second argumentSERVER. It will generate the trace for using the discovery server.NoteDepending on your configuration oftcpdump, this script may requiresudoprivileges to read traffic across your network device.After both executions are done, run the Python script to generate a graph similar to the one


key: chroma:document
string_value:
run the Python script to generate a graph similar to the one below.$exportFASTRTPS_DEFAULT_PROFILES_FILE="no_intraprocess_configuration.xml"$sudobashgenerate_discovery_packages.bash~/ros2/install/local_setup.bash$sudobashgenerate_discovery_packages.bash~/ros2/install/local_setup.bashSERVER$python3discovery_packets.pyThis graph is the result of a specific run of the experiment. The reader can execute the scripts and generate their own results for comparison. It can easily be seen that network traffic is reduced when using discovery service.The reduction in traffic is a result of avoiding every node announcing itself and waiting a response from every other node on the network. This creates a huge amount of traffic in large architectures. The reduction from this method increases with the number of nodes, making this architecture more scalable than the Simple Discovery Protocol approach.The new Fast DDS Discovery Server v2 is available sinceFast DDSv2.0.2, replacing the old discovery server. In this new version,


key: chroma:document
string_value:
replacing the old discovery server. In this new version, those nodes that do not share topics will automatically not discover each other, saving the whole discovery data required to connect them and their endpoints. The experiment above does not show this case, but even so the massive reduction in traffic can be appreciated due to the hidden infrastructure topics of ROS 2 nodes.


key: chroma:document
string_value:
Code Examples:

Language: unknown

fastdds discovery -

server

id 0

Language: unknown

export ROS_DISCOVERY_SERVER=127.0.0.1:11811

Language: unknown

set ROS_DISCOVERY_SERVER=127.0.0.1:11811

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_discovery_server

Language: unknown

export ROS_DISCOVERY_SERVER=127.0.0.1:11811

Language: unknown

set ROS_DISCOVERY_SERVER=127.0.0.1:11811

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_discovery_server

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=simple_listener

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=simple_talker

Language: unknown

fastdds discovery -

server

id 0 -

ip

address 127.0.0.1 -

port 11811

Language: unknown

fastdds discovery -

server

id 1 -

ip

address 127.0.0.1 -

port 11888

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown


key: chroma:document
string_value:
Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Language: unknown

fastdds discovery -

server

id 0 -

ip

address 127.0.0.1 -

port 11811 -

backup

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Language: unknown

fastdds discovery -

server

id 0 -

ip


key: chroma:document
string_value:
Language: unknown

fastdds discovery -

server

id 0 -

ip

address 127.0.0.1 -

port 11811

Language: unknown

fastdds discovery -

server

id 1 -

ip

address 127.0.0.1 -

port 11888

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_1

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_1

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_2

Language: unknown

export ROS_DISCOVERY_SERVER=";127.0.0.1:11888"

Language: unknown


key: chroma:document
string_value:
Language: unknown

set ROS_DISCOVERY_SERVER=";127.0.0.1:11888"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_2

Language: unknown

<?xml version="1.0" encoding="UTF

8" ?><dds><profilesxmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles"><participantprofile_name="super_client_profile"is_default_profile="true"><rtps><builtin><discovery_config><discoveryProtocol>SUPER_CLIENT</discoveryProtocol><discoveryServersList><RemoteServerprefix="44.53.00.5f.45.50.52.4f.53.49.4d.41"><metatrafficUnicastLocatorList><locator><udpv4><address>127.0.0.1</address><port>11811</port></udpv4></locator></metatrafficUnicastLocatorList></RemoteServer></discoveryServersList></discovery_config></builtin></rtps></participant></profiles></dds>

Language: unknown

fastdds discovery

i 0

l 127.0.0.1

p 11811

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"


key: chroma:document
string_value:
Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker

Language: unknown

export FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown

set FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown ros2 daemon stopros2 daemon startros2 topic listros2 node info /talkerros2 topic info /chatterros2 topic echo /chatter

Language: unknown

export FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown

set FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown

rqt_graph

Language: unknown

fastdds discovery

i 0

l 127.0.0.1

p 11811

Language: unknown


key: chroma:document
string_value:
i 0

l 127.0.0.1

p 11811

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Language: unknown

export ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown

set ROS_DISCOVERY_SERVER="127.0.0.1:11811"

Language: unknown ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker

Language: unknown

export FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown

set FASTRTPS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml

Language: unknown ros2 topic list --no-daemonros2 node info /talker --no-daemon --spin-time 2

Language: unknown

$exportFASTRTPS_DEFAULT_PROFILES_FILE="no_intraprocess_configuration.xml"$sudobashgenerate_discovery_packages.bash~/ros2/install/local_setup.bash$sudobashgenerate_discovery_packages.bash~/ros2/install/local_setup.bashSERVER$python3discovery_packets.py


key: chroma:document
string_value:
Title: Setting up a robot simulation (Basic) URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Simulators/Webots/Setting-Up-Simulation-Webots-Basic.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Setting up a robot simulation (Basic)Goal:Setup a robot simulation and control it from ROS 2.Tutorial level:AdvancedTime:30 minutesContentsBackgroundPrerequisitesTasks1 Create the package structure2 Setup the simulation world3 Edit themy_robot_driverplugin4 Create themy_robot.urdffile5 Create the launch file6 Edit additional files7 Test the codeSummaryNext stepsBackgroundIn this tutorial, you are going to use the Webots robot simulator to set-up and run a very simple ROS 2 simulation scenario.Thewebots_ros2package provides an interface between ROS 2 and Webots. It includes several sub-packages, but in this tutorial, you are going to use only thewebots_ros2_driversub-package to implement a Python or C++ plugin controlling a simulated robot. Some other sub-packages contain demos with different robots such as the TurtleBot3. They are documented in theWebots ROS 2 examplespage.PrerequisitesIt is recommended to understand basic ROS principles covered in the beginnerTutorials. In particular,Using turtlesim,


key: chroma:document
string_value:
in the beginnerTutorials. In particular,Using turtlesim, ros2, and rqt,Understanding topics,Creating a workspace,Creating a packageandCreating a launch fileare useful prerequisites.LinuxWindowsmacOSThe Linux and ROS commands of this tutorial can be run in a standard Linux terminal. The following pageInstallation (Ubuntu)explains how to install thewebots_ros2package on Linux.The Linux and ROS commands of this tutorial must be run in a WSL (Windows Subsystem for Linux) environment. The following pageInstallation (Windows)explains how to install thewebots_ros2package on Windows.The Linux and ROS commands of this tutorial must be run in a pre-configured Linux Virtual Machine (VM). The following pageInstallation (macOS)explains how to install thewebots_ros2package on macOS.This tutorial is compatible with version 2023.1.0 ofwebots_ros2and Webots R2023b, as well as upcoming versions.Tasks1 Create the package structureLet’s organize the code in a custom ROS 2 package. Create a new package namedmy_packagefrom


key: chroma:document
string_value:
custom ROS 2 package. Create a new package namedmy_packagefrom thesrcfolder of your ROS 2 workspace. Change the current directory of your terminal toros2_ws/srcand run:PythonC++ros2 pkg create --build-type ament_python --license Apache-2.0 --node-name my_robot_driver my_package --dependencies rclpy geometry_msgs webots_ros2_driverThe--node-namemy_robot_driveroption will create amy_robot_driver.pytemplate Python plugin in themy_packagesubfolder that you will modify later. The--dependenciesrclpygeometry_msgswebots_ros2_driveroption specifies the packages needed by themy_robot_driver.pyplugin in thepackage.xmlfile.Let’s add alaunchand aworldsfolder inside themy_packagefolder.cd my_packagemkdir launchmkdir worldsYou should end up with the following folder structure:src/└── my_package/├── launch/├── my_package/│   ├── __init__.py│   └── my_robot_driver.py├── resource/│   └── my_package├── test/│   ├── test_copyright.py│   ├── test_flake8.py│   └── test_pep257.py├── worlds/├── package.xml├── setup.cfg└──


key: chroma:document
string_value:
└── test_pep257.py├── worlds/├── package.xml├── setup.cfg└── setup.pyros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name MyRobotDriver my_package --dependencies rclcpp geometry_msgs webots_ros2_driver pluginlibThe--node-nameMyRobotDriveroption will create aMyRobotDriver.cpptemplate C++ plugin in themy_package/srcsubfolder that you will modify later. The--dependenciesrclcppgeometry_msgswebots_ros2_driverpluginliboption specifies the packages needed by theMyRobotDriverplugin in thepackage.xmlfile.Let’s add alaunch, aworldsand aresourcefolder inside themy_packagefolder.cd my_packagemkdir launchmkdir worldsmkdir resourceTwo additional files must be created: the header file forMyRobotDriverand themy_robot_driver.xmlpluginlib description file.touch my_robot_driver.xmltouch include/my_package/MyRobotDriver.hppYou should end up with the following folder structure:src/└── my_package/├── include/│   └── my_package/│       └── MyRobotDriver.hpp├── launch/├── resource/├── src/│   └──


key: chroma:document
string_value:
└── MyRobotDriver.hpp├── launch/├── resource/├── src/│   └── MyRobotDriver.cpp├── worlds/├── CMakeList.txt├── my_robot_driver.xml└── package.xml2 Setup the simulation worldYou will need a world file containing a robot to launch your simulation.Downloadthisworldfileand move it insidemy_package/worlds/.This is actually a fairly simple text file you can visualize in a text editor. A simple robot is already included in thismy_world.wbtworld file.NoteIn case you want to learn how to create your own robot model in Webots, you can check thistutorial.3 Edit themy_robot_driverpluginThewebots_ros2_driversub-package automatically creates a ROS 2 interface for most sensors. More details on existing device interfaces and how to configure them is given in the second part of the tutorial:Setting up a robot simulation (Advanced). In this task, you will extend this interface by creating your own custom plugin. This custom plugin is a ROS node equivalent to a robot controller. You can use it to access theWebots robot


key: chroma:document
string_value:
to a robot controller. You can use it to access theWebots robot APIand create your own topics and services to control your robot.NoteThe purpose of this tutorial is to show a basic example with a minimum number of dependencies. However, you could avoid the use of this plugin by using anotherwebots_ros2sub-package namedwebots_ros2_control, introducing a new dependency. This other sub-package creates an interface with theros2_controlpackage that facilitates the control of a differential wheeled robot.PythonC++Openmy_package/my_package/my_robot_driver.pyin your favorite editor and replace its contents with the following:importrclpyfromgeometry_msgs.msgimportTwistHALF_DISTANCE_BETWEEN_WHEELS=0.045WHEEL_RADIUS=0.025classMyRobotDriver:definit(self,webots_node,properties):self.__robot=webots_node.robotself.__left_motor=self.__robot.getDevice('left wheel motor')self.__right_motor=self.__robot.getDevice('right wheel


key: chroma:document
string_value:
motor')self.__right_motor=self.__robot.getDevice('right wheel motor')self.__left_motor.setPosition(float('inf'))self.__left_motor.setVelocity(0)self.__right_motor.setPosition(float('inf'))self.__right_motor.setVelocity(0)self.__target_twist=Twist()rclpy.init(args=None)self.__node=rclpy.create_node('my_robot_driver')self.__node.create_subscription(Twist,'cmd_vel',self.__cmd_vel_callback,1)def__cmd_vel_callback(self,twist):self.__target_twist=twistdefstep(self):rclpy.spin_once(self.__node,timeout_sec=0)forward_speed=self.__target_twist.linear.xangular_speed=self.__target_twist.angular.zcommand_motor_left=(forward_speed-angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUScommand_motor_right=(forward_speed+angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUSself.__left_motor.setVelocity(command_motor_left)self.__right_motor.setVelocity(command_motor_right)As you can see, theMyRobotDriverclass implements three methods.The first method, namedinit(self,...), is actually the ROS node counterpart of the


key: chroma:document
string_value:
is actually the ROS node counterpart of the Python__init__(self,...)constructor. Theinitmethod always takes two arguments:Thewebots_nodeargument contains a reference on the Webots instance.Thepropertiesargument is a dictionary created from the XML tags given in the URDF files (4 Create the my_robot.urdf file) and allows you to pass parameters to the controller.The robot instance from the simulationself.__robotcan be used to access theWebots robot API. Then, it gets the two motor instances and initializes them with a target position and a target velocity. Finally a ROS node is created and a callback method is registered for a ROS topic named/cmd_velthat will handleTwistmessages.definit(self,webots_node,properties):self.__robot=webots_node.robotself.__left_motor=self.__robot.getDevice('left wheel motor')self.__right_motor=self.__robot.getDevice('right wheel


key: chroma:document
string_value:
motor')self.__right_motor=self.__robot.getDevice('right wheel motor')self.__left_motor.setPosition(float('inf'))self.__left_motor.setVelocity(0)self.__right_motor.setPosition(float('inf'))self.__right_motor.setVelocity(0)self.__target_twist=Twist()rclpy.init(args=None)self.__node=rclpy.create_node('my_robot_driver')self.__node.create_subscription(Twist,'cmd_vel',self.__cmd_vel_callback,1)Then comes the implementation of the__cmd_vel_callback(self,twist)callback private method that will be called for eachTwistmessage received on the/cmd_veltopic and will save it in theself.__target_twistmember variable.def__cmd_vel_callback(self,twist):self.__target_twist=twistFinally, thestep(self)method is called at every time step of the simulation. The call torclpy.spin_once()is needed to keep the ROS node running smoothly. At each time step, the method will retrieve the desiredforward_speedandangular_speedfromself.__target_twist. As the motors are controlled with angular velocities, the method will then convert


key: chroma:document
string_value:
with angular velocities, the method will then convert theforward_speedandangular_speedinto individual commands for each wheel. This conversion depends on the structure of the robot, more specifically on the radius of the wheel and the distance between them.defstep(self):rclpy.spin_once(self.__node,timeout_sec=0)forward_speed=self.__target_twist.linear.xangular_speed=self.__target_twist.angular.zcommand_motor_left=(forward_speed-angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUScommand_motor_right=(forward_speed+angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUSself.__left_motor.setVelocity(command_motor_left)self.__right_motor.setVelocity(command_motor_right)Openmy_package/include/my_package/MyRobotDriver.hppin your favorite editor and replace its contents with the following:#ifndef WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP#define


key: chroma:document
string_value:
the following:#ifndef WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP#define WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP#include"rclcpp/macros.hpp"#include"webots_ros2_driver/PluginInterface.hpp"#include"webots_ros2_driver/WebotsNode.hpp"#include"geometry_msgs/msg/twist.hpp"#include"rclcpp/rclcpp.hpp"namespacemy_robot_driver{classMyRobotDriver:publicwebots_ros2_driver::PluginInterface{public:voidstep()override;voidinit(webots_ros2_driver::WebotsNode*node,std::unordered_map<std::string,std::string>&parameters)override;private:rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtrcmd_vel_subscription_;geometry_msgs::msg::Twistcmd_vel_msg;WbDeviceTagright_motor;WbDeviceTagleft_motor;};}// namespace my_robot_driver#endifThe classMyRobotDriveris defined, which inherits from thewebots_ros2_driver::PluginInterfaceclass. The plugin has to overridestep(...)andinit(...)functions. More details are given in theMyRobotDriver.cppfile. Several helper methods, callbacks and member variables that will be used internally by the plugin are declared


key: chroma:document
string_value:
that will be used internally by the plugin are declared privately.Then, openmy_package/src/MyRobotDriver.cppin your favorite editor and replace its contents with the following:#include"my_package/MyRobotDriver.hpp"#include"rclcpp/rclcpp.hpp"#include<cstdio>#include<functional>#include<webots/motor.h>#include<webots/robot.h>#define HALF_DISTANCE_BETWEEN_WHEELS 0.045#define WHEEL_RADIUS 0.025namespacemy_robot_driver{voidMyRobotDriver::init(webots_ros2_driver::WebotsNode*node,std::unordered_map<std::string,std::string>&parameters){right_motor=wb_robot_get_device("right wheel motor");left_motor=wb_robot_get_device("left wheel


key: chroma:document
string_value:
wheel motor");left_motor=wb_robot_get_device("left wheel motor");wb_motor_set_position(left_motor,INFINITY);wb_motor_set_velocity(left_motor,0.0);wb_motor_set_position(right_motor,INFINITY);wb_motor_set_velocity(right_motor,0.0);cmd_vel_subscription_=node->create_subscription<geometry_msgs::msg::Twist>("/cmd_vel",rclcpp::SensorDataQoS().reliable(),[this](constgeometry_msgs::msg::Twist::SharedPtrmsg){this->cmd_vel_msg.linear=msg->linear;this->cmd_vel_msg.angular=msg->angular;});}voidMyRobotDriver::step(){autoforward_speed=cmd_vel_msg.linear.x;autoangular_speed=cmd_vel_msg.angular.z;autocommand_motor_left=(forward_speed-angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;autocommand_motor_right=(forward_speed+angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;wb_motor_set_velocity(left_motor,command_motor_left);wb_motor_set_velocity(right_motor,command_motor_right);}}// namespace


key: chroma:document
string_value:
namespace my_robot_driver#include"pluginlib/class_list_macros.hpp"PLUGINLIB_EXPORT_CLASS(my_robot_driver::MyRobotDriver,webots_ros2_driver::PluginInterface)TheMyRobotDriver::initmethod is executed once the plugin is loaded by thewebots_ros2_driverpackage. It takes two arguments:A pointer to theWebotsNodedefined bywebots_ros2_driver, which allows to access the ROS 2 node functions.Theparametersargument is an unordered map of strings, created from the XML tags given in the URDF files (4 Create the my_robot.urdf file) and allows to pass parameters to the controller. It is not used in this example.It initializes the plugin by setting up the robot motors, setting their positions and velocities, and subscribing to the/cmd_veltopic.voidMyRobotDriver::init(webots_ros2_driver::WebotsNode*node,std::unordered_map<std::string,std::string>&parameters){right_motor=wb_robot_get_device("right wheel motor");left_motor=wb_robot_get_device("left wheel


key: chroma:document
string_value:
wheel motor");left_motor=wb_robot_get_device("left wheel motor");wb_motor_set_position(left_motor,INFINITY);wb_motor_set_velocity(left_motor,0.0);wb_motor_set_position(right_motor,INFINITY);wb_motor_set_velocity(right_motor,0.0);cmd_vel_subscription_=node->create_subscription<geometry_msgs::msg::Twist>("/cmd_vel",rclcpp::SensorDataQoS().reliable(),[this](constgeometry_msgs::msg::Twist::SharedPtrmsg){this->cmd_vel_msg.linear=msg->linear;this->cmd_vel_msg.angular=msg->angular;});}The subscription callback is declared as a lambda function, that will be called for each Twist message received on the/cmd_veltopic and will save it in thecmd_vel_msgmember variable.[this](constgeometry_msgs::msg::Twist::SharedPtrmsg){this->cmd_vel_msg.linear=msg->linear;this->cmd_vel_msg.angular=msg->angular;}Thestep()method is called at every time step of the simulation. At each time step, the method will retrieve the desiredforward_speedandangular_speedfromcmd_vel_msg. As the motors are controlled with angular velocities, the


key: chroma:document
string_value:
As the motors are controlled with angular velocities, the method will then convert theforward_speedandangular_speedinto individual commands for each wheel. This conversion depends on the structure of the robot, more specifically on the radius of the wheel and the distance between them.voidMyRobotDriver::step(){autoforward_speed=cmd_vel_msg.linear.x;autoangular_speed=cmd_vel_msg.angular.z;autocommand_motor_left=(forward_speed-angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;autocommand_motor_right=(forward_speed+angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;wb_motor_set_velocity(left_motor,command_motor_left);wb_motor_set_velocity(right_motor,command_motor_right);}The final lines of the file define the end of themy_robot_drivernamespace and include a macro to export theMyRobotDriverclass as a plugin using thePLUGINLIB_EXPORT_CLASSmacro. This allows the plugin to be loaded by the Webots ROS2 driver at


key: chroma:document
string_value:
allows the plugin to be loaded by the Webots ROS2 driver at runtime.#include"pluginlib/class_list_macros.hpp"PLUGINLIB_EXPORT_CLASS(my_robot_driver::MyRobotDriver,webots_ros2_driver::PluginInterface)NoteWhile the plugin is implemented in C++, the C API must be used to interact with the Webots controller library.4 Create themy_robot.urdffileYou now have to create a URDF file to declare theMyRobotDriverplugin. This will allow thewebots_ros2_driverROS node to launch the plugin and connect it to the target robot.In themy_package/resourcefolder create a text file namedmy_robot.urdfwith this content:PythonC++<?xml version="1.0" ?><robotname="My robot"><webots><plugintype="my_package.my_robot_driver.MyRobotDriver"/></webots></robot>Thetypeattribute specifies the path to the class given by the hierarchical structure of files.webots_ros2_driveris responsible for loading the class based on the specified package and modules.<?xml version="1.0" ?><robotname="My


key: chroma:document
string_value:
package and modules.<?xml version="1.0" ?><robotname="My robot"><webots><plugintype="my_robot_driver::MyRobotDriver"/></webots></robot>Thetypeattribute specifies the namespace and class name to load.pluginlibis responsible for loading the class based on the specified information.NoteThis simple URDF file doesn’t contain any link or joint information about the robot as it is not needed in this tutorial. However, URDF files usually contain much more information as explained in theURDFtutorial.NoteHere the plugin does not take any input parameter, but this can be achieved with a tag containing the parameter name.PythonC++<plugintype="my_package.my_robot_driver.MyRobotDriver"><parameterName>someValue</parameterName></plugin><plugintype="my_robot_driver::MyRobotDriver"><parameterName>someValue</parameterName></plugin>This is namely used to pass parameters to existing Webots device plugins (seeSetting up a robot simulation (Advanced)).5 Create the launch fileLet’s create the launch file to easily launch the


key: chroma:document
string_value:
launch fileLet’s create the launch file to easily launch the simulation and the ROS controller with a single command. In themy_package/launchfolder create a new text file namedrobot_launch.pywith this


key: chroma:document
string_value:
create a new text file namedrobot_launch.pywith this code:importosimportlaunchfromlaunchimportLaunchDescriptionfromament_index_python.packagesimportget_package_share_directoryfromwebots_ros2_driver.webots_launcherimportWebotsLauncherfromwebots_ros2_driver.webots_controllerimportWebotsControllerdefgenerate_launch_description():package_dir=get_package_share_directory('my_package')robot_description_path=os.path.join(package_dir,'resource','my_robot.urdf')webots=WebotsLauncher(world=os.path.join(package_dir,'worlds','my_world.wbt'))my_robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path},])returnLaunchDescription([webots,my_robot_driver,launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))])TheWebotsLauncherobject is a custom action that allows you to start a Webots simulation instance. You have to specify in the constructor which world


key: chroma:document
string_value:
instance. You have to specify in the constructor which world file the simulator will open.webots=WebotsLauncher(world=os.path.join(package_dir,'worlds','my_world.wbt'))Then, the ROS node interacting with the simulated robot is created. This node, namedWebotsController, is located in thewebots_ros2_driverpackage.LinuxWindowsmacOSThe node will be able to communicate with the simulated robot by using a custom protocol based on IPC and shared memory.The node (in WSL) will be able to communicate with the simulated robot (in Webots on native Windows) through a TCP connection.The node (in the docker container) will be able to communicate with the simulated robot (in Webots on native macOS) through a TCP connection.In your case, you need to run a single instance of this node, because you have a single robot in the simulation. But if you had more robots in the simulation, you would have to run one instance of this node per robot. Therobot_nameparameter is used to define the name of the robot the driver should connect


key: chroma:document
string_value:
used to define the name of the robot the driver should connect to. Therobot_descriptionparameter holds the path to the URDF file which refers to theMyRobotDriverplugin. You can see theWebotsControllernode as the interface that connects your controller plugin to the target robot.my_robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path},])After that, the two nodes are set to be launched in theLaunchDescriptionconstructor:returnLaunchDescription([webots,my_robot_driver,Finally, an optional part is added in order to shutdown all the nodes once Webots terminates (e.g., when it gets closed from the graphical user interface).launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))NoteMore details onWebotsControllerandWebotsLauncherarguments can be foundon the nodes reference page.6 Edit additional filesPythonC++Before you can start the launch


key: chroma:document
string_value:
Edit additional filesPythonC++Before you can start the launch file, you have to modify thesetup.pyfile to include the extra files you added. Openmy_package/setup.pyand replace its contents with:fromsetuptoolsimportfind_packages,setuppackage_name='my_package'data_files=[]data_files.append(('share/ament_index/resource_index/packages',['resource/'+package_name]))data_files.append(('share/'+package_name+'/launch',['launch/robot_launch.py']))data_files.append(('share/'+package_name+'/worlds',['worlds/my_world.wbt']))data_files.append(('share/'+package_name+'/resource',['resource/my_robot.urdf']))data_files.append(('share/'+package_name,['package.xml']))setup(name=package_name,version='0.0.0',packages=find_packages(exclude=['test']),data_files=data_files,install_requires=['setuptools'],zip_safe=True,maintainer='user',maintainer_email='user.name@mail.com',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts':['my_robot_driver =


key: chroma:document
string_value:
= my_package.my_robot_driver:main',],},)This sets-up the package and adds in thedata_filesvariable the newly added files:my_world.wbt,my_robot.urdfandrobot_launch.py.Before you can start the launch file, you have to modifyCMakeLists.txtandmy_robot_driver.xmlfiles:CMakeLists.txtdefines the compilation rules of your plugin.my_robot_driver.xmlis necessary for the pluginlib to find your Webots ROS 2 plugin.Openmy_package/my_robot_driver.xmland replace its contents with:<librarypath="my_package"><!-- The `type` attribute is a reference to the plugin class. --><!-- The `base_class_type` attribute is always `webots_ros2_driver::PluginInterface`. --><classtype="my_robot_driver::MyRobotDriver"base_class_type="webots_ros2_driver::PluginInterface"><description>ThisisaWebotsROS2pluginexample</description></class></library>Openmy_package/CMakeLists.txtand replace its contents with:cmake_minimum_required(VERSION3.5)project(my_package)if(NOTCMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD14)endif()# Besides the package specific


key: chroma:document
string_value:
Besides the package specific dependencies we also need the `pluginlib` and `webots_ros2_driver`find_package(ament_cmakeREQUIRED)find_package(rclcppREQUIRED)find_package(std_msgsREQUIRED)find_package(geometry_msgsREQUIRED)find_package(pluginlibREQUIRED)find_package(webots_ros2_driverREQUIRED)# Export the plugin configuration filepluginlib_export_plugin_description_file(webots_ros2_drivermy_robot_driver.xml)# MyRobotDriver libraryadd_library(${PROJECT_NAME}SHAREDsrc/MyRobotDriver.cpp)target_include_directories(${PROJECT_NAME}PRIVATEinclude)ament_target_dependencies(${PROJECT_NAME}pluginlibrclcppwebots_ros2_driver)install(TARGETS${PROJECT_NAME}ARCHIVEDESTINATIONlibLIBRARYDESTINATIONlibRUNTIMEDESTINATIONbin)# Install additional directories.install(DIRECTORYlaunchresourceworldsDESTINATIONshare/${PROJECT_NAME}/)ament_export_include_directories(include)ament_export_libraries(${PROJECT_NAME})ament_package()The CMakeLists.txt exports the plugin configuration file with thepluginlib_export_plugin_description_file(),


key: chroma:document
string_value:
file with thepluginlib_export_plugin_description_file(), defines a shared library of the C++ pluginsrc/MyRobotDriver.cpp, and sets the include and library dependencies usingament_target_dependencies().The file then installs the library, the directorieslaunch,resource, andworldsto theshare/my_packagedirectory. Finally, it exports the include directories and libraries usingament_export_include_directories()andament_export_libraries(), respectively, and declares the package usingament_package().7 Test the codeLinuxWindowsmacOSFrom a terminal in your ROS 2 workspace run:colcon buildsource install/local_setup.bashros2 launch my_package robot_launch.pyThis will launch the simulation. Webots will be automatically installed on the first run in case it was not already installed.From a terminal in your WSL ROS 2 workspace run:colcon buildexport WEBOTS_HOME=/mnt/c/Program\ Files/Webotssource install/local_setup.bashros2 launch my_package robot_launch.pyBe sure to use the/mntprefix in front of your path to the Webots


key: chroma:document
string_value:
sure to use the/mntprefix in front of your path to the Webots installation folder to access the Windows file system from WSL.This will launch the simulation. Webots will be automatically installed on the first run in case it was not already installed.On macOS, a local server must be started on the host to start Webots from the VM. The local server can be downloadedon the webots-server repository.In a terminal of the host machine (not in the VM), specify the Webots installation folder (e.g./Applications/Webots.app) and start the server using the following commands:export WEBOTS_HOME=/Applications/Webots.apppython3 local_simulation_server.pyFrom a terminal in the Linux VM in your ROS 2 workspace, build and launch your custom package with:colcon buildsource install/local_setup.bashros2 launch my_package robot_launch.pyNoteIf you want to install Webots manually, you can download ithere.Then, open a second terminal and send a command with:ros2 topic pub /cmd_vel geometry_msgs/Twist  "linear: { x: 0.1 }"The robot


key: chroma:document
string_value:
pub /cmd_vel geometry_msgs/Twist  "linear: { x: 0.1 }"The robot is now moving forward.At this point, the robot is able to blindly follow your motor commands. But it will eventually bump into the wall as you order it to move forwards.Close the Webots window, this should also shutdown your ROS nodes started from the launcher. Close also the topic command withCtrl+Cin the second terminal.SummaryIn this tutorial, you set-up a realistic robot simulation with Webots and implemented a custom plugin to control the motors of the robot.Next stepsTo improve the simulation, the robot’s sensors can be used to detect obstacles and avoid them. The second part of the tutorial shows how to implement such behaviour:Setting up a robot simulation (Advanced).


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 pkg create -

build

type ament_python -

license Apache

2.0 -

node

name my_robot_driver my_package -

dependencies rclpy geometry_msgs webots_ros2_driver

Language: unknown

cd my_packagemkdir launchmkdir worlds

Language: unknown src/└── my_package/├── launch/├── my_package/│   ├── __init__.py│   └── my_robot_driver.py├── resource/│   └── my_package├── test/│   ├── test_copyright.py│   ├── test_flake8.py│   └── test_pep257.py├── worlds/├── package.xml├── setup.cfg└── setup.py

Language: unknown ros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name MyRobotDriver my_package --dependencies rclcpp geometry_msgs webots_ros2_driver pluginlib

Language: unknown cd my_packagemkdir launchmkdir worldsmkdir resource

Language: unknown

touch my_robot_driver.xmltouch include/my_package/MyRobotDriver.hpp


key: chroma:document
string_value:
Language: unknown src/└── my_package/├── include/│   └── my_package/│       └── MyRobotDriver.hpp├── launch/├── resource/├── src/│   └── MyRobotDriver.cpp├── worlds/├── CMakeList.txt├── my_robot_driver.xml└── package.xml


key: chroma:document
string_value:
Language: unknown importrclpyfromgeometry_msgs.msgimportTwistHALF_DISTANCE_BETWEEN_WHEELS=0.045WHEEL_RADIUS=0.025classMyRobotDriver:definit(self,webots_node,properties):self.__robot=webots_node.robotself.__left_motor=self.__robot.getDevice('left wheel motor')self.__right_motor=self.__robot.getDevice('right wheel


key: chroma:document
string_value:
motor')self.__right_motor=self.__robot.getDevice('right wheel motor')self.__left_motor.setPosition(float('inf'))self.__left_motor.setVelocity(0)self.__right_motor.setPosition(float('inf'))self.__right_motor.setVelocity(0)self.__target_twist=Twist()rclpy.init(args=None)self.__node=rclpy.create_node('my_robot_driver')self.__node.create_subscription(Twist,'cmd_vel',self.__cmd_vel_callback,1)def__cmd_vel_callback(self,twist):self.__target_twist=twistdefstep(self):rclpy.spin_once(self.__node,timeout_sec=0)forward_speed=self.__target_twist.linear.xangular_speed=self.__target_twist.angular.zcommand_motor_left=(forward_speed-angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUScommand_motor_right=(forward_speed+angular_speed*HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUSself.__left_motor.setVelocity(command_motor_left)self.__right_motor.setVelocity(command_motor_right)


key: chroma:document
string_value:
Language: unknown definit(self,webots_node,properties):self.__robot=webots_node.robotself.__left_motor=self.__robot.getDevice('left wheel motor')self.__right_motor=self.__robot.getDevice('right wheel motor')self.__left_motor.setPosition(float('inf'))self.__left_motor.setVelocity(0)self.__right_motor.setPosition(float('inf'))self.__right_motor.setVelocity(0)self.__target_twist=Twist()rclpy.init(args=None)self.__node=rclpy.create_node('my_robot_driver')self.__node.create_subscription(Twist,'cmd_vel',self.__cmd_vel_callback,1)

Language: unknown

def__cmd_vel_callback(self,twist):self.__target_twist=twist

Language: unknown

defstep(self):rclpy.spin_once(self.__node,timeout_sec=0)forward_speed=self.__target_twist.linear.xangular_speed=self.__target_twist.angular.zcommand_motor_left=(forward_speed

angular_speed

HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUScommand_motor_right=(forward_speed+angular_speed


key: chroma:document
string_value:
HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUSself.__left_motor.setVelocity(command_motor_left)self.__right_motor.setVelocity(command_motor_right)

Language: unknown

#ifndef WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP#define WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP#include"rclcpp/macros.hpp"#include"webots_ros2_driver/PluginInterface.hpp"#include"webots_ros2_driver/WebotsNode.hpp"#include"geometry_msgs/msg/twist.hpp"#include"rclcpp/rclcpp.hpp"namespacemy_robot_driver{classMyRobotDriver:publicwebots_ros2_driver::PluginInterface{public:voidstep()override;voidinit(webots_ros2_driver::WebotsNode

node,std::unordered_map<std::string,std::string>&parameters)override;private:rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtrcmd_vel_subscription_;geometry_msgs::msg::Twistcmd_vel_msg;WbDeviceTagright_motor;WbDeviceTagleft_motor;};}// namespace my_robot_driver#endif


key: chroma:document
string_value:
Language: unknown #include"my_package/MyRobotDriver.hpp"#include"rclcpp/rclcpp.hpp"#include<cstdio>#include<functional>#include<webots/motor.h>#include<webots/robot.h>#define HALF_DISTANCE_BETWEEN_WHEELS 0.045#define WHEEL_RADIUS 0.025namespacemy_robot_driver{voidMyRobotDriver::init(webots_ros2_driver::WebotsNode*node,std::unordered_map<std::string,std::string>&parameters){right_motor=wb_robot_get_device("right wheel motor");left_motor=wb_robot_get_device("left wheel


key: chroma:document
string_value:
namespace my_robot_driver#include"pluginlib/class_list_macros.hpp"PLUGINLIB_EXPORT_CLASS(my_robot_driver::MyRobotDriver,webots_ros2_driver::PluginInterface)


key: chroma:document
string_value:
Language: unknown voidMyRobotDriver::init(webots_ros2_driver::WebotsNode*node,std::unordered_map<std::string,std::string>&parameters){right_motor=wb_robot_get_device("right wheel motor");left_motor=wb_robot_get_device("left wheel motor");wb_motor_set_position(left_motor,INFINITY);wb_motor_set_velocity(left_motor,0.0);wb_motor_set_position(right_motor,INFINITY);wb_motor_set_velocity(right_motor,0.0);cmd_vel_subscription_=node->create_subscription<geometry_msgs::msg::Twist>("/cmd_vel",rclcpp::SensorDataQoS().reliable(),[this](constgeometry_msgs::msg::Twist::SharedPtrmsg){this->cmd_vel_msg.linear=msg->linear;this->cmd_vel_msg.angular=msg->angular;});}

Language: unknown

[this](constgeometry_msgs::msg::Twist::SharedPtrmsg){this

>cmd_vel_msg.linear=msg

>linear;this

>cmd_vel_msg.angular=msg

>angular;}

Language: unknown

voidMyRobotDriver::step(){autoforward_speed=cmd_vel_msg.linear.x;autoangular_speed=cmd_vel_msg.angular.z;autocommand_motor_left=(forward_speed

angular_speed


key: chroma:document
string_value:
angular_speed

HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;autocommand_motor_right=(forward_speed+angular_speed

HALF_DISTANCE_BETWEEN_WHEELS)/WHEEL_RADIUS;wb_motor_set_velocity(left_motor,command_motor_left);wb_motor_set_velocity(right_motor,command_motor_right);}

Language: unknown

#include"pluginlib/class_list_macros.hpp"PLUGINLIB_EXPORT_CLASS(my_robot_driver::MyRobotDriver,webots_ros2_driver::PluginInterface)

Language: unknown

<?xml version="1.0" ?><robotname="My robot"><webots><plugintype="my_package.my_robot_driver.MyRobotDriver"/></webots></robot>

Language: unknown

<?xml version="1.0" ?><robotname="My robot"><webots><plugintype="my_robot_driver::MyRobotDriver"/></webots></robot>

Language: unknown

<plugintype="my_package.my_robot_driver.MyRobotDriver"><parameterName>someValue</parameterName></plugin>

Language: unknown

<plugintype="my_robot_driver::MyRobotDriver"><parameterName>someValue</parameterName></plugin>

Language: unknown


key: chroma:document
string_value:
Language: unknown

importosimportlaunchfromlaunchimportLaunchDescriptionfromament_index_python.packagesimportget_package_share_directoryfromwebots_ros2_driver.webots_launcherimportWebotsLauncherfromwebots_ros2_driver.webots_controllerimportWebotsControllerdefgenerate_launch_description():package_dir=get_package_share_directory('my_package')robot_description_path=os.path.join(package_dir,'resource','my_robot.urdf')webots=WebotsLauncher(world=os.path.join(package_dir,'worlds','my_world.wbt'))my_robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path},])returnLaunchDescription([webots,my_robot_driver,launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))])

Language: unknown

webots=WebotsLauncher(world=os.path.join(package_dir,'worlds','my_world.wbt'))

Language: unknown


key: chroma:document
string_value:
Language: unknown

my_robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path},])

Language: unknown

returnLaunchDescription([webots,my_robot_driver,

Language: unknown

launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))


key: chroma:document
string_value:
Language: unknown fromsetuptoolsimportfind_packages,setuppackage_name='my_package'data_files=[]data_files.append(('share/ament_index/resource_index/packages',['resource/'+package_name]))data_files.append(('share/'+package_name+'/launch',['launch/robot_launch.py']))data_files.append(('share/'+package_name+'/worlds',['worlds/my_world.wbt']))data_files.append(('share/'+package_name+'/resource',['resource/my_robot.urdf']))data_files.append(('share/'+package_name,['package.xml']))setup(name=package_name,version='0.0.0',packages=find_packages(exclude=['test']),data_files=data_files,install_requires=['setuptools'],zip_safe=True,maintainer='user',maintainer_email='user.name@mail.com',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts':['my_robot_driver = my_package.my_robot_driver:main',],},)


key: chroma:document
string_value:
Language: unknown <librarypath="my_package"><!-- The `type` attribute is a reference to the plugin class. --><!-- The `base_class_type` attribute is always `webots_ros2_driver::PluginInterface`. --><classtype="my_robot_driver::MyRobotDriver"base_class_type="webots_ros2_driver::PluginInterface"><description>ThisisaWebotsROS2pluginexample</description></class></library>


key: chroma:document
string_value:
Language: unknown cmake_minimum_required(VERSION3.5)project(my_package)if(NOTCMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD14)endif()# Besides the package specific dependencies we also need the `pluginlib` and `webots_ros2_driver`find_package(ament_cmakeREQUIRED)find_package(rclcppREQUIRED)find_package(std_msgsREQUIRED)find_package(geometry_msgsREQUIRED)find_package(pluginlibREQUIRED)find_package(webots_ros2_driverREQUIRED)# Export the plugin configuration filepluginlib_export_plugin_description_file(webots_ros2_drivermy_robot_driver.xml)# MyRobotDriver libraryadd_library(${PROJECT_NAME}SHAREDsrc/MyRobotDriver.cpp)target_include_directories(${PROJECT_NAME}PRIVATEinclude)ament_target_dependencies(${PROJECT_NAME}pluginlibrclcppwebots_ros2_driver)install(TARGETS${PROJECT_NAME}ARCHIVEDESTINATIONlibLIBRARYDESTINATIONlibRUNTIMEDESTINATIONbin)# Install additional


key: chroma:document
string_value:
Install additional directories.install(DIRECTORYlaunchresourceworldsDESTINATIONshare/${PROJECT_NAME}/)ament_export_include_directories(include)ament_export_libraries(${PROJECT_NAME})ament_package()


key: chroma:document
string_value:
Language: unknown colcon buildsource install/local_setup.bashros2 launch my_package robot_launch.py

Language: unknown colcon buildexport WEBOTS_HOME=/mnt/c/Program\ Files/Webotssource install/local_setup.bashros2 launch my_package robot_launch.py

Language: unknown

export WEBOTS_HOME=/Applications/Webots.apppython3 local_simulation_server.py

Language: unknown colcon buildsource install/local_setup.bashros2 launch my_package robot_launch.py

Language: unknown ros2 topic pub /cmd_vel geometry_msgs/Twist  "linear: { x: 0.1 }"


key: chroma:document
string_value:
Title: Using time (C++)

URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Tf2/Learning

About

Tf2

And

Time

Cpp.html

Section: Installation

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


key: chroma:document
string_value:
Using time (C++)Goal:Learn how to get a transform at a specific time and wait for a transform to be available on the tf2 tree usinglookupTransform()function.Tutorial level:IntermediateTime:10 minutesContentsBackgroundTasks1 Update the listener node2 Fix the listener node3 Check the resultsSummaryBackgroundIn previous tutorials, we recreated the turtle demo by writing atf2 broadcasterand atf2 listener. We also learned how toadd a new frame to the transformation treeand learned how tf2 keeps track of a tree of coordinate frames. This tree changes over time, and tf2 stores a time snapshot for every transform (for up to 10 seconds by default). Until now we used thelookupTransform()function to get access to the latest available transforms in that tf2 tree, without knowing at what time that transform was recorded. This tutorial will teach you how to get a transform at a specific time.Tasks1 Update the listener nodeLet’s go back to where we ended in theadding a frame tutorial. Go to thelearning_tf2_cpppackage.


key: chroma:document
string_value:
theadding a frame tutorial. Go to thelearning_tf2_cpppackage. Openturtle_tf2_listener.cppand take a look at thelookupTransform()call:try{t=tf_buffer_->lookupTransform(toFrameRel,fromFrameRel,tf2::TimePointZero);}catch(consttf2::TransformException&ex){You can see that we specified a time equal to 0 by callingtf2::TimePointZero.NoteThetf2package has it’s own time typetf2::TimePoint, which is different fromrclcpp::Time. Many APIs in the packagetf2_rosautomatically convert betweenrclcpp::Timeandtf2::TimePoint.rclcpp::Time(0,0,this->get_clock()->get_clock_type())could have been used here, but it would have been converted totf2::TimePointZeroanyways.For tf2, time 0 means “the latest available” transform in the buffer. Now, change this line to get the transform at the current time,this->get_clock()->now():rclcpp::Timenow=this->get_clock()->now();try{t=tf_buffer_->lookupTransform(toFrameRel,fromFrameRel,now);}catch(consttf2::TransformException&ex){Now build the package and try to run the launch file.ros2 launch


key: chroma:document
string_value:
build the package and try to run the launch file.ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.pyYou will notice that it fails and outputs something similar to this:[INFO] [1629873136.345688064] [listener]: Could not transform turtle2 to turtle1: Lookup wouldrequire extrapolation into the future.  Requested time 1629873136.345539 but the latest datais at time 1629873136.338804, when looking up transform from frame [turtle1] to frame [turtle2]It tells you that the frame does not exist or that the data is in the future.To understand why is this happening we need to understand how buffers work. Firstly, each listener has a buffer where it stores all the coordinate transforms coming from the different tf2 broadcasters. Secondly, when a broadcaster sends out a transform, it takes some time before that transform gets into the buffer (usually a couple of milliseconds). As a result, when you request a frame transform at time “now”, you should wait a few milliseconds for that information to arrive.2 Fix the


key: chroma:document
string_value:
a few milliseconds for that information to arrive.2 Fix the listener nodetf2 provides a nice tool that will wait until a transform becomes available. You use this by adding a timeout parameter tolookupTransform(). To fix this, edit your code as shown below (add the last timeout parameter):rclcpp::Timenow=this->get_clock()->now();try{t=tf_buffer_->lookupTransform(toFrameRel,fromFrameRel,now,50ms);}catch(consttf2::TransformException&ex){ThelookupTransform()can take four arguments, where the last one is an optional timeout. It will block for up to that duration waiting for it to timeout.3 Check the resultsYou can now build the package and run the launch file.ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.pyYou should notice thatlookupTransform()will actually block until the transform between the two turtles becomes available (this will usually take a few milliseconds). Once the timeout has been reached (fifty milliseconds in this case), an exception will be raised only if the transform is still not


key: chroma:document
string_value:
an exception will be raised only if the transform is still not available.SummaryIn this tutorial, you learned how to acquire a transform at a specific timestamp and how to wait for a transform to be available on the tf2 tree when using thelookupTransform()function.


key: chroma:document
string_value:
Code Examples:

Language: unknown

try{t=tf_buffer_

>lookupTransform(toFrameRel,fromFrameRel,tf2::TimePointZero);}catch(consttf2::TransformException&ex){

Language: unknown

rclcpp::Timenow=this

>get_clock()

>now();try{t=tf_buffer_

>lookupTransform(toFrameRel,fromFrameRel,now);}catch(consttf2::TransformException&ex){

Language: unknown

ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.py

Language: unknown [INFO] [1629873136.345688064] [listener]: Could not transform turtle2 to turtle1: Lookup wouldrequire extrapolation into the future.  Requested time 1629873136.345539 but the latest datais at time 1629873136.338804, when looking up transform from frame [turtle1] to frame [turtle2]

Language: unknown

rclcpp::Timenow=this

>get_clock()

>now();try{t=tf_buffer_

>lookupTransform(toFrameRel,fromFrameRel,now,50ms);}catch(consttf2::TransformException&ex){

Language: unknown

ros2 launch learning_tf2_cpp turtle_tf2_demo_launch.py


key: chroma:document
string_value:
Title: Migrating Launch Files

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

To

Guides/Migrating

from

ROS1/Migrating

Launch

Files.html

Section: Installation

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


key: chroma:document
string_value:
Migrating Launch FilesTable of ContentsBackgroundMigrating tagsNew tags in ROS 2Replacing an include tagSubstitutionsType inference rulesWhile launch files in ROS 1 are always specified using.xmlfiles, ROS 2 supports Python scripts to enable more flexibility (seelaunch package) as well as XML and YAML files.This guide describes how to write ROS 2 XML launch files for an easy migration from ROS 1.BackgroundA description of the ROS 2 launch system and its Python API can be found inLaunch System tutorial.Migrating tagslaunchAvailable in ROS 1.launchis the root element of any ROS 2 launch XML file.nodeAvailable in ROS 1.Launches a new node.Differences from ROS 1:typeattribute is nowexec.nsattribute is nownamespace.The following attributes aren’t available:machine,respawn_delay,clear_params.Example<launch><nodepkg="demo_nodes_cpp"exec="talker"/><nodepkg="demo_nodes_cpp"exec="listener"/></launch>paramAvailable in ROS 1.Used for passing a parameter to a node.There’s no global parameter concept in ROS 2. For


key: chroma:document
string_value:
to a node.There’s no global parameter concept in ROS 2. For that reason, it can only be used nested in anodetag. Some attributes aren’t supported in ROS 2:type,textfile,binfile,executable.Thecommandattribute is nowvalue="$(command'...')".Example<launch><nodepkg="demo_nodes_cpp"exec="parameter_event"><paramname="foo"value="5"/></node></launch>Type inference rulesHere are some examples of how to write parameters:<nodepkg="my_package"exec="my_executable"name="my_node"><!--A string parameter with value "1"--><paramname="a_string"value="'1'"/><!--A integer parameter with value 1--><paramname="an_int"value="1"/><!--A float parameter with value 1.0--><paramname="a_float"value="1.0"/><!--A string parameter with value "asd"--><paramname="another_string"value="asd"/><!--Another string parameter, with value "asd"--><paramname="string_with_same_value_as_above"value="'asd'"/><!--Another string parameter, with value "'asd'"--><paramname="quoted_string"value="\'asd\'"/><!--A list of strings, with value ["asd", "bsd",


key: chroma:document
string_value:
list of strings, with value ["asd", "bsd", "csd"]--><paramname="list_of_strings"value="asd, bsd, csd"value-sep=", "/><!--A list of ints, with value [1, 2, 3]--><paramname="list_of_ints"value="1,2,3"value-sep=","/><!--Another list of strings, with value ["1", "2", "3"]--><paramname="another_list_of_strings"value="'1';'2';'3'"value-sep=";"/><!--A list of strings using an strange separator, with value ["1", "2", "3"]--><paramname="strange_separator"value="'1'//'2'//'3'"value-sep="//"/></node>Parameter groupingIn ROS 2,paramtags are allowed to be nested. For example:<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramname="group1"><paramname="group2"><paramname="my_param"value="1"/></param><paramname="another_param"value="2"/></param></node>That will create two parameters:Agroup1.group2.my_paramof value1, hosted by node/an_absolute_ns/my_node.Agroup1.another_paramof value2hosted by node/an_absolute_ns/my_node.It’s also possible to use full parameter


key: chroma:document
string_value:
also possible to use full parameter names:<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramname="group1.group2.my_param"value="1"/><paramname="group1.another_param"value="2"/></node>rosparamAvailable in ROS 1.Loads parameters from a yaml file.It has been replaced with afromattribute inparamtags.Example<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramfrom="/path/to/file"/></node>remapAvailable in ROS 1.Used to pass remapping rules to a node.It can only be used withinnodetags.Example<launch><nodepkg="demo_nodes_cpp"exec="talker"><remapfrom="chatter"to="my_topic"/></node><nodepkg="demo_nodes_cpp"exec="listener"><remapfrom="chatter"to="my_topic"/></node></launch>includeAvailable in ROS 1.Allows including another launch file.Differences from ROS 1:Available in ROS 1, included content was scoped. In ROS 2, it’s not. Nest includes ingrouptags to scope them.nsattribute is not supported. See example ofpush_ros_namespacetag for a


key: chroma:document
string_value:
is not supported. See example ofpush_ros_namespacetag for a workaround.argtags nested in anincludetag don’t support conditionals (if,unless) or thedescriptionattribute.There is no support for nestedenvtags.set_envandunset_envcan be used instead.Bothclear_paramsandpass_all_argsattributes aren’t supported.ExamplesSeeReplacing an include tag.argAvailable in ROS 1.argis used for declaring a launch argument, or to pass an argument when usingincludetags.Differences from ROS 1:valueattribute is not allowed. Uselettag for this.docis nowdescription.When nested within anincludetag,if,unless, anddescriptionattributes aren’t allowed.Example<launch><argname="topic_name"default="chatter"/><nodepkg="demo_nodes_cpp"exec="talker"><remapfrom="chatter"to="$(var topic_name)"/></node><nodepkg="demo_nodes_cpp"exec="listener"><remapfrom="chatter"to="$(var topic_name)"/></node></launch>Passing an argument to the launch fileIn the XML launch file above, thetopic_namedefaults to the namechatter, but can be configured on the


key: chroma:document
string_value:
to the namechatter, but can be configured on the command-line. Assuming the above launch configuration is in a file namedmylaunch.xml, a different topic name can be used by launching it with the following:ros2launchmylaunch.xmltopic_name:=custom_topic_nameThere is some additional information about passing command-line arguments inUsing Substitutions.envAvailable in ROS 1.Sets an environment variable.It has been replaced withenv,set_envandunset_env:envcan only be used nested in anodeorexecutabletag.ifandunlesstags aren’t supported.set_envcan be nested within the root taglaunchor ingrouptags. It accepts the same attributes asenv, and alsoifandunlesstags.unset_envunsets an environment variable. It accepts anameattribute and


key: chroma:document
string_value:
an environment variable. It accepts anameattribute and conditionals.Example<launch><set_envname="MY_ENV_VAR"value="MY_VALUE"if="CONDITION_A"/><set_envname="ANOTHER_ENV_VAR"value="ANOTHER_VALUE"unless="CONDITION_B"/><set_envname="SOME_ENV_VAR"value="SOME_VALUE"/><nodepkg="MY_PACKAGE"exec="MY_EXECUTABLE"name="MY_NODE"><envname="NODE_ENV_VAR"value="SOME_VALUE"/></node><unset_envname="MY_ENV_VAR"if="CONDITION_A"/><nodepkg="ANOTHER_PACKAGE"exec="ANOTHER_EXECUTABLE"name="ANOTHER_NODE"/><unset_envname="ANOTHER_ENV_VAR"unless="CONDITION_B"/><unset_envname="SOME_ENV_VAR"/></launch>groupAvailable in ROS 1.Allows limiting the scope of launch configurations. Usually used together withlet,includeandpush_ros_namespacetags.Differences from ROS 1:There is nonsattribute. See the newpush_ros_namespacetag as a workaround.clear_paramsattribute isn’t available.It doesn’t acceptremapnorparamtags as children.Examplelaunch-prefixconfiguration affects bothexecutableandnodetags’ actions. This example will usetimeas a prefix


key: chroma:document
string_value:
actions. This example will usetimeas a prefix ifuse_time_prefix_in_talkerargument is1, only for the talker.<launch><argname="use_time_prefix_in_talker"default="0"/><group><letname="launch-prefix"value="time"if="$(var use_time_prefix_in_talker)"/><nodepkg="demo_nodes_cpp"exec="talker"/></group><nodepkg="demo_nodes_cpp"exec="listener"/></launch>machineIt is not supported at the moment.testIt is not supported at the moment.New tags in ROS 2set_env and unset_envSeeenvtag decription.push_ros_namespaceincludeandgrouptags don’t accept annsattribute. This action can be used as a workaround:<!-Other tags--><group><push_ros_namespacenamespace="my_ns"/><!--Nodes here are namespaced with "my_ns".--><!--If there is an include action here, its nodes will also be namespaced.--><push_ros_namespacenamespace="another_ns"/><!--Nodes here are namespaced with "another_ns/my_ns".--><push_ros_namespacenamespace="/absolute_ns"/><!--Nodes here are namespaced with "/absolute_ns".--><!--The following node receives an absolute


key: chroma:document
string_value:
"/absolute_ns".--><!--The following node receives an absolute namespace, so it will ignore the others previously pushed.--><!--The full path of the node will be /asd/my_node.--><nodepkg="my_pkg"exec="my_executable"name="my_node"ns="/asd"/></group><!--Nodes outside the group action won't be namespaced.--><!-Other tags-->letIt’s a replacement ofargtag with a value attribute.<letname="foo"value="asd"/>executableIt allows running any executable.Example<executablecmd="ls -las"cwd="/var/log"name="my_exec"launch-prefix="something"output="screen"shell="true"><envname="LD_LIBRARY"value="/lib/some.so"/></executable>Replacing an include tagIn order to include a launch file under anamespaceas in ROS 1 then theincludetags must be nested in agrouptag.<group><includefile="another_launch_file"/></group>Then, instead of using thensattribute, add thepush_ros_namespaceaction tag to specify the namespace:<group><push_ros_namespacenamespace="my_ns"/><includefile="another_launch_file"/></group>Nestingincludetags under


key: chroma:document
string_value:
under agrouptag is only required when specifying a namespaceSubstitutionsDocumentation about ROS 1’s substitutions can be found inroslaunch XML wiki. Substitutions syntax hasn’t changed, i.e. it still follows the$(substitution-namearg1arg2...)pattern. There are, however, some changes w.r.t. ROS 1:envandoptenvtags have been replaced by theenvtag.$(env<NAME>)will fail if the environment variable doesn’t exist.$(env<NAME>'')does the same as ROS 1’s$(optenv<NAME>).$(env<NAME><DEFAULT>)does the same as ROS 1’s$(env<NAME><DEFAULT>)or$(optenv<NAME><DEFAULT>).findhas been replaced withfind-pkg-share(substituting the share directory of an installed package). Alternativelyfind-pkg-prefixwill return the root of an installed package.There is a newexec-in-pkgsubstitution. e.g.:$(exec-in-pkg<package_name><exec_name>).There is a newfind-execsubstitution.arghas been replaced withvar. It looks at configurations defined either withargorlettag.evalanddirnamesubstitutions require escape characters for string values,


key: chroma:document
string_value:
require escape characters for string values, e.g.if="$(eval'\'$(varvariable)\'==\'val1\'')".anonsubstitution is not supported.Type inference rulesThe rules that were shown inTypeinferencerulessubsection ofparamtag applies to any attribute. For example:<!--Setting a string value to an attribute expecting an int will raise an error.--><tag1attr-expecting-an-int="'1'"/><!--Correct version.--><tag1attr-expecting-an-int="1"/><!--Setting an integer in an attribute expecting a string will raise an error.--><tag2attr-expecting-a-str="1"/><!--Correct version.--><tag2attr-expecting-a-str="'1'"/><!--Setting a list of strings in an attribute expecting a string will raise an error.--><tag3attr-expecting-a-str="asd, bsd"str-attr-sep=", "/><!--Correct version.--><tag3attr-expecting-a-str="don't use a separator"/>Some attributes accept more than a single type, for examplevalueattribute ofparamtag. It’s usual that parameters that are of typeint(orfloat) also accept anstr, that will be later substituted and tried to convert


key: chroma:document
string_value:
Code Examples:

Language: unknown

<launch><nodepkg="demo_nodes_cpp"exec="talker"/><nodepkg="demo_nodes_cpp"exec="listener"/></launch>

Language: unknown

<launch><nodepkg="demo_nodes_cpp"exec="parameter_event"><paramname="foo"value="5"/></node></launch>


key: chroma:document
string_value:
Language: unknown <nodepkg="my_package"exec="my_executable"name="my_node"><!--A string parameter with value "1"--><paramname="a_string"value="'1'"/><!--A integer parameter with value 1--><paramname="an_int"value="1"/><!--A float parameter with value 1.0--><paramname="a_float"value="1.0"/><!--A string parameter with value "asd"--><paramname="another_string"value="asd"/><!--Another string parameter, with value "asd"--><paramname="string_with_same_value_as_above"value="'asd'"/><!--Another string parameter, with value "'asd'"--><paramname="quoted_string"value="\'asd\'"/><!--A list of strings, with value ["asd", "bsd", "csd"]--><paramname="list_of_strings"value="asd, bsd, csd"value-sep=", "/><!--A list of ints, with value [1, 2, 3]--><paramname="list_of_ints"value="1,2,3"value-sep=","/><!--Another list of strings, with value ["1", "2", "3"]--><paramname="another_list_of_strings"value="'1';'2';'3'"value-sep=";"/><!--A list of strings using an strange separator, with value ["1", "2",


key: chroma:document
string_value:
of strings using an strange separator, with value ["1", "2", "3"]--><paramname="strange_separator"value="'1'//'2'//'3'"value-sep="//"/></node>


key: chroma:document
string_value:
Language: unknown

<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramname="group1"><paramname="group2"><paramname="my_param"value="1"/></param><paramname="another_param"value="2"/></param></node>

Language: unknown

<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramname="group1.group2.my_param"value="1"/><paramname="group1.another_param"value="2"/></node>

Language: unknown

<nodepkg="my_package"exec="my_executable"name="my_node"ns="/an_absoulute_ns"><paramfrom="/path/to/file"/></node>

Language: unknown

<launch><nodepkg="demo_nodes_cpp"exec="talker"><remapfrom="chatter"to="my_topic"/></node><nodepkg="demo_nodes_cpp"exec="listener"><remapfrom="chatter"to="my_topic"/></node></launch>

Language: unknown

<launch><argname="topic_name"default="chatter"/><nodepkg="demo_nodes_cpp"exec="talker"><remapfrom="chatter"to="$(var topic_name)"/></node><nodepkg="demo_nodes_cpp"exec="listener"><remapfrom="chatter"to="$(var topic_name)"/></node></launch>


key: chroma:document
string_value:
Language: unknown

ros2launchmylaunch.xmltopic_name:=custom_topic_name

Language: unknown

<launch><set_envname="MY_ENV_VAR"value="MY_VALUE"if="CONDITION_A"/><set_envname="ANOTHER_ENV_VAR"value="ANOTHER_VALUE"unless="CONDITION_B"/><set_envname="SOME_ENV_VAR"value="SOME_VALUE"/><nodepkg="MY_PACKAGE"exec="MY_EXECUTABLE"name="MY_NODE"><envname="NODE_ENV_VAR"value="SOME_VALUE"/></node><unset_envname="MY_ENV_VAR"if="CONDITION_A"/><nodepkg="ANOTHER_PACKAGE"exec="ANOTHER_EXECUTABLE"name="ANOTHER_NODE"/><unset_envname="ANOTHER_ENV_VAR"unless="CONDITION_B"/><unset_envname="SOME_ENV_VAR"/></launch>

Language: unknown

<launch><argname="use_time_prefix_in_talker"default="0"/><group><letname="launch

prefix"value="time"if="$(var use_time_prefix_in_talker)"/><nodepkg="demo_nodes_cpp"exec="talker"/></group><nodepkg="demo_nodes_cpp"exec="listener"/></launch>


key: chroma:document
string_value:
Language: unknown <!-Other tags--><group><push_ros_namespacenamespace="my_ns"/><!--Nodes here are namespaced with "my_ns".--><!--If there is an include action here, its nodes will also be namespaced.--><push_ros_namespacenamespace="another_ns"/><!--Nodes here are namespaced with "another_ns/my_ns".--><push_ros_namespacenamespace="/absolute_ns"/><!--Nodes here are namespaced with "/absolute_ns".--><!--The following node receives an absolute namespace, so it will ignore the others previously pushed.--><!--The full path of the node will be /asd/my_node.--><nodepkg="my_pkg"exec="my_executable"name="my_node"ns="/asd"/></group><!--Nodes outside the group action won't be namespaced.--><!-Other tags-->

Language: unknown

<letname="foo"value="asd"/>

Language: unknown

<executablecmd="ls

las"cwd="/var/log"name="my_exec"launch

prefix="something"output="screen"shell="true"><envname="LD_LIBRARY"value="/lib/some.so"/></executable>

Language: unknown

<group><includefile="another_launch_file"/></group>


key: chroma:document
string_value:
<group><includefile="another_launch_file"/></group>

Language: unknown

<group><push_ros_namespacenamespace="my_ns"/><includefile="another_launch_file"/></group>

Language: unknown <!--Setting a string value to an attribute expecting an int will raise an error.--><tag1attr-expecting-an-int="'1'"/><!--Correct version.--><tag1attr-expecting-an-int="1"/><!--Setting an integer in an attribute expecting a string will raise an error.--><tag2attr-expecting-a-str="1"/><!--Correct version.--><tag2attr-expecting-a-str="'1'"/><!--Setting a list of strings in an attribute expecting a string will raise an error.--><tag3attr-expecting-a-str="asd, bsd"str-attr-sep=", "/><!--Correct version.--><tag3attr-expecting-a-str="don't use a separator"/>


key: chroma:document
string_value:
Title: Understanding the security keystore URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Security/The-Keystore.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Understanding the security keystoreGoal:Explore files located in the ROS 2 security keystore.Tutorial level:AdvancedTime:15 minutesContentsBackgroundSecurity Artifact LocationsPublic Key MaterialsPrivate Key MaterialsDomain Governance PolicySecurity EnclavesTake the quiz!BackgroundBefore proceeding ensure you have completed theSetting up securitytutorial.Thesros2package can be used to create keys, certificates and policies necessary to enable ROS 2 security. However, the security configuration is extrememly flexible. A basic understanding of the ROS 2 Security Keystore will allow integration with an existing PKI (Public Key Infrastructure) and managment of sensitive key materials consistent with organizational policies.Security Artifact LocationsWith communications security enabled in the prior tutorial, let’s take a look at the files which were created when security was enabled. These are the files which make encryption possible.Thesros2utilities (ros2security...) separate files into public, private and


key: chroma:document
string_value:
(ros2security...) separate files into public, private and enclave key materials.ROS uses the directory defined by the environmental variableROS_SECURITY_KEYSTOREas the keystore. For this tutorial, we use the directory~/sros2_demo/demo_keystore.Public Key MaterialsYou will find three encryption certificates in the public directory at~/sros2_demo/demo_keystore/public; however, the identity and permissions certificates are actually just a link to the Certificate Authority (CA) certificate.In a public key infrastructure, theCertificate Authorityacts as a trust anchor: it validates the identities and permissions of participants. For ROS, that means all the nodes that participate in the ROS graph (which may extend to an entire fleet of individual robots). By placing the Certificate Authority’s certificate (ca.cert.pem) in the proper location on the robot, all ROS nodes can establish mutual trust with other nodes using the same Certificate Authority.Although in our tutorials we create a Certificate Authority


key: chroma:document
string_value:
in our tutorials we create a Certificate Authority on-the-fly, in a production system this should be done according to a pre-defined security plan. Typically the Certificate Authority for a production system will be created off-line, and placed on the robot during initial setup. It may be unique for each robot, or shared across a fleet of robots all intended to trust each other.DDS (and ROS, by extension) supports separation of identity and permission trust chains, so each function has its own certificate authority. In most cases a ROS system security plan does not require a separation between these duties, so the security utilities generate a single Certificate Authority which is used for both identity and permissions.Useopensslto view this x509 certificate and display it as text:cd~/sros2_demo/demo_keystore/public opensslx509-inca.cert.pem-text-nooutThe output should look similar to the


key: chroma:document
string_value:
output should look similar to the following:Certificate:Data:Version:3(0x2)SerialNumber:02:8e:9a:24:ea:10:55:cb:e6:ea:e8:7a:c0:5f:58:6d:37:42:78:aaSignatureAlgorithm:ecdsa-with-SHA256Issuer:CN=sros2CAValidityNotBefore:Jun116:57:372021GMTNotAfter:May3116:57:372031GMTSubject:CN=sros2CASubjectPublicKeyInfo:PublicKeyAlgorithm:id-ecPublicKeyPublic-Key:(256bit)pub:04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:dc:ed:39:c5:32ASN1OID:prime256v1NISTCURVE:P-256X509v3extensions:X509v3BasicConstraints:criticalCA:TRUE,pathlen:1SignatureAlgorithm:ecdsa-with-SHA25630:45:02:21:00:d4:fc:d8:45:ff:a4:51:49:98:4c:f0:c4:3f:e0:e7:33:19:8e:31:3c:d0:43:e7:e9:8f:36:f0:90:18:ed:d7:7d:02:20:30:84:f7:04:33:87:bb:4f:d3:8b:95:61:48:df:83:4b:e5:92:b3:e6:ee:3c:d5:cf:30:43:09:04:71:bd:dd:7cSome things to note about this CA certificate:The certificate subject namesros2CAis the default provided by


key: chroma:document
string_value:
certificate subject namesros2CAis the default provided by thesros2utilities.This certificate is valid for ten years from time of creationLike all certificates, this contains a public key used for public-private key encryptionAs a Root Certificate Authority, this is aself-signed certificate; i.e., it is signed using its own private key.Since this is a public certificate, it can be freely copied as needed to establish trust throughout your ROS system.Private Key MaterialsPrivate key materials can be found in the keystore directory~/sros2_demo/demo_keystore/private. Similar to thepublicdirectory, this contains one certificate authority keyca.key.pemand symbolic links to it to be used as both an Identity and a Permissions CA private key.WarningProtect this private key and create a secure backup of it!This is the private key associated with the public Certificate Authority which serves as the anchor for all security in your ROS system. You will use it to modify encryption policies for the ROS graph and to add


key: chroma:document
string_value:
it to modify encryption policies for the ROS graph and to add new ROS participants. Depending upon your robot’s security needs, the key can be protected with access permissions and locked down to another account, or it can be moved off the robot entirely and onto another system or device. If the file is lost, you will be unable to change access permissions and add new participants to the system. Similarly, any user or process with access to the file has the ability to modify system policies and participants.This file is only required for configuring the robot, but is not needed for the robot to run. It can safely be stored offline in another system or removable media.Thesros2utilities useelliptic curve cryptograpyrather than RSA for improved security and reduced key size. Use the following command to show details about this elliptic curve private key:cd~/sros2_demo/demo_keystore/private opensslec-inca.key.pem-text-nooutYour output should look similar to the


key: chroma:document
string_value:
output should look similar to the following:readECkeyPrivate-Key:(256bit)priv:93:da:76:b9:e3:91:ab:e9:42:76:f2:38:f1:9d:94:90:5e:b5:96:7b:7f:71:ee:13:1b:d4:a0:f9:48:fb:ae:77pub:04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:dc:ed:39:c5:32ASN1OID:prime256v1NISTCURVE:P-256In addition to the private key itself, note that the public key is listed, and it matches the public key listed in the Certificate Authorityca.cert.pem.Domain Governance PolicyFind the domain governance policy in the enclave directory within the keystore,~/sros2_demo/demo_keystore/enclaves. Theenclavedirectory contains XML governance policy documentgovernance.xml, as well as a copy of the document which has been signed by the Permissions CA asgovernance.p7s.Thegovernance.p7sfile contains domain-wide settings such as how to handle unauthenticated participants, whether to encrypt discovery, and default rules for


key: chroma:document
string_value:
whether to encrypt discovery, and default rules for access to topics.Use the following command to validate theS/MIME signatureof the governance file:opensslsmime-verify-ingovernance.p7s-CAfile../public/permissions_ca.cert.pemThis command will print out the XML document, and the last line will beVerificationsuccessfulto show that the document was properly signed by the Permissions CA.Security EnclavesSecure processes (typically ROS nodes) run within a security enclave. In the simplest case, all the processes can be consolidated into the same enclave, and all processes will then use the same security policy. However, to apply different policies to different processes, the processes can use different security enclaves when starting. For more details about security enclaves, see thedesign document. The security enclave is specifed by using the ROS argument--enclavewhen running a node.Each security enclave requires six filesin order to enable security. Each filemustbe named as defined below, and as outlined in


key: chroma:document
string_value:
Each filemustbe named as defined below, and as outlined in theDDS Security standard. In order to avoid having mulitple copies of the same files, thesros2utilities create links for each enclave to the single governance policy, the Identity CA and Permissions CA descibed above.See the following six files within thelistenerenclave. Three are specific to this enclave, while three are generic to this ROS system:key.pem, the private key used to encrypt and decrypt within this enclavecert.pem, the public certificate for this enclave; this certificate has been signed by the Identity CApermissions.p7s, the permissions for this enclave; this file has been signed with the Permissions CAgovernance.p7s, a link to the signed security policy file for this domainidentity_ca.cert.pem, a link to the Identity CA for this domainpermissions_ca.cert.pem, a link to the Permissions CA for this domainThe private encryption keykey.pemshould be protected according to your security plan. This key encrypts, decrypts and validates


key: chroma:document
string_value:
your security plan. This key encrypts, decrypts and validates communications within this specific enclave. Should the key be lost or stolen, revoke the key and create a new identity for this enclave.The filepermissions.xmlhas also been created in this directory and can be used to recreate the signed permissions file. However, this file is not required to enable security since DDS uses the signed version of the file instead.Take the quiz!See if you can answer these questions about the ROS security keystore. Begin with a new terminal session and enable security with the keystore created in the prior tutorial:exportROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystoreexportROS_SECURITY_ENABLE=trueexportROS_SECURITY_STRATEGY=Enforcecd~/sros2_demo/demo_keystore/enclaves/talker_listener/listenerMake a backup copy ofpermissions.p7sbefore beginning.Question 1Answer 1Openpermissions.p7sin a text editor. Make a negligible change to the XML content (e.g., add a space or a blank line) and save the file. Launch the listener


key: chroma:document
string_value:
a space or a blank line) and save the file. Launch the listener node:ros2rundemo_nodes_cpplistener--ros-args--enclave/talker_listener/listenerWhat do you expect to happen?Can you launch the talker node?ros2rundemo_nodes_cpptalker--ros-args--enclave/talker_listener/talkerWhat is the difference between launching the listener and launching the talker?The listener fails to launch and throws an error. When thepermissions.p7sfile was modified–however minor–the file’s signature became invalid. A node will not launch with security enabled and enforced when the permissions file is invalid.The talker will start as expected. It uses thepermissions.p7sfile in a different enclave, and the file is still valid.Question 2Answer 2What command lets you check to see if the signature on the modifiedpermissions.p7sfile is valid?Check thatpermissions.p7shas been properly signed by the Permissions CA using theopensslsmimecommand:opensslsmime-verify-inpermissions.p7s-CAfilepermissions_ca.cert.pemRestore your original, properly


key: chroma:document
string_value:
Code Examples:

Language: unknown

cd~/sros2_demo/demo_keystore/public

opensslx509

inca.cert.pem

text

noout

Language: unknown

Certificate:Data:Version:3(0x2)SerialNumber:02:8e:9a:24:ea:10:55:cb:e6:ea:e8:7a:c0:5f:58:6d:37:42:78:aaSignatureAlgorithm:ecdsa

with

SHA256Issuer:CN=sros2CAValidityNotBefore:Jun116:57:372021GMTNotAfter:May3116:57:372031GMTSubject:CN=sros2CASubjectPublicKeyInfo:PublicKeyAlgorithm:id

ecPublicKeyPublic

Key:(256bit)pub:04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:dc:ed:39:c5:32ASN1OID:prime256v1NISTCURVE:P

256X509v3extensions:X509v3BasicConstraints:criticalCA:TRUE,pathlen:1SignatureAlgorithm:ecdsa

with

SHA25630:45:02:21:00:d4:fc:d8:45:ff:a4:51:49:98:4c:f0:c4:3f:e0:e7:33:19:8e:31:3c:d0:43:e7:e9:8f:36:f0:90:18:ed:d7:7d:02:20:30:84:f7:04:33:87:bb:4f:d3:8b:95:61:48:df:83:4b:e5:92:b3:e6:ee:3c:d5:cf:30:43:09:04:71:bd:dd:7c

Language: unknown


key: chroma:document
string_value:
Language: unknown

cd~/sros2_demo/demo_keystore/private

opensslec

inca.key.pem

text

noout

Language: unknown

readECkeyPrivate

Key:(256bit)priv:93:da:76:b9:e3:91:ab:e9:42:76:f2:38:f1:9d:94:90:5e:b5:96:7b:7f:71:ee:13:1b:d4:a0:f9:48:fb:ae:77pub:04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:dc:ed:39:c5:32ASN1OID:prime256v1NISTCURVE:P

256

Language: unknown

opensslsmime

verify

ingovernance.p7s

CAfile../public/permissions_ca.cert.pem

Language: unknown

exportROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystoreexportROS_SECURITY_ENABLE=trueexportROS_SECURITY_STRATEGY=Enforcecd~/sros2_demo/demo_keystore/enclaves/talker_listener/listener

Language: unknown

ros2rundemo_nodes_cpplistener-

ros

args-

enclave/talker_listener/listener

Language: unknown

ros2rundemo_nodes_cpptalker-

ros

args-

enclave/talker_listener/talker

Language: unknown

opensslsmime

verify


key: chroma:document
string_value:
Title: The ROS_DOMAIN_ID

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

Section: Installation

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

The ROS_DOMAIN_IDTable of ContentsOverviewChoosing a domain ID (short version)Choosing a domain ID (long version)Platform-specific constraintsParticipant constraintsDomain ID to UDP Port CalculatorOverviewAs explained elsewhere, the default middleware that ROS 2 uses for communication is DDS.

In DDS, the primary mechanism for having different logical networks share a physical network is known as the Domain ID.

ROS 2 nodes on the same domain can freely discover and send messages to each other, while ROS 2 nodes on different domains cannot.

All ROS 2 nodes use domain ID 0 by default.


key: chroma:document
string_value:
All ROS 2 nodes use domain ID 0 by default.

To avoid interference between different groups of computers running ROS 2 on the same network, a different domain ID should be set for each group.Choosing a domain ID (short version)The text below explains the derivation of the range of domain IDs that should be used in ROS 2.

To skip that background and just choose a safe number, simply choose a domain ID between 0 and 101, inclusive.Choosing a domain ID (long version)The domain ID is used by DDS to compute the UDP ports that will be used for discovery and communication.

Seethis articlefor details on how the ports are computed.

Remembering our basic networking, the UDP port is anunsigned 16-bit integer.

Thus, the highest port number that can be allocated is 65535.


key: chroma:document
string_value:
Thus, the highest port number that can be allocated is 65535.

Doing some math with the formula in the article above, this means that the highest domain ID that can possibly be assigned is 232, while the lowest that can be assigned is 0.Platform-specific constraintsFor maximum compatibility, some additional platform-specific constraints should be followed when choosing a domain ID.

In particular, it is best to avoid allocating domain IDs in the operating system’sephemeral port range.

This avoids possible conflicts between the ports used by the ROS 2 nodes and other networking services on the computers.Here are some platform-specific notes about ephemeral ports.LinuxmacOSWindowsBy default, the Linux kernel uses ports 32768-60999 for ephemeral ports.

This means that domain IDs 0-101 and 215-232 can be safely used without colliding with ephemeral ports.

The ephemeral port range is configurable in Linux by setting custom values in/proc/sys/net/ipv4/ip_local_port_range.


key: chroma:document
string_value:
If a custom ephemeral port range is used, the above numbers may have to be adjusted accordingly.By default, the ephemeral port range on macOS is 49152-65535.

This means that domain IDs 0-166 can be safely used without colliding with ephemeral ports.

The ephemeral port range is configurable in macOS by setting custom sysctl values fornet.inet.ip.portrange.firstandnet.inet.ip.portrange.last.

If a custom ephemeral port range is used, the above numbers may have to be adjusted accordingly.By default, the ephemeral port range on Windows is 49152-65535.

This means that domain IDs 0-166 can be safely used without colliding with ephemeral ports.

The ephemeral port range is configurable in Windows byusing netsh.

If a custom ephemeral port range is used, the above numbers may have to be adjusted accordingly.Participant constraintsFor each ROS 2 process running on a computer, one DDS “participant” is created.


key: chroma:document
string_value:
Since each DDS participant takes up two ports on the computer, running more than 120 ROS 2 processes on one computer may spill over into other domain IDs or the ephemeral ports.To see why, consider the domain IDs 1 and 2.Domain ID 1 uses port 7650 and 7651 for multicast.Domain ID 2 uses port 7900 and 7901 for multicast.When creating the 1st process (zeroth participant) in domain ID 1, the ports 7660 and 7661 are used for unicast.When creating the 120th process (119th participant) in domain ID 1, the ports 7898 and 7899 are used for unicast.When creating the 121st process (120th participant) in domain ID 1, the ports 7900 and 7901 are used for unicast and overlap with domain ID 2.If it is known that the computer will only ever be on a single domain ID at a time, and the domain ID is low enough, it is safe to create more ROS 2 processes than this.When choosing a domain ID that is near the top of the range of platform-specific domain IDs, one additional constraint should be considered.For instance, assume a


key: chroma:document
string_value:
constraint should be considered.For instance, assume a Linux computer with a domain ID of 101:The zero’th ROS 2 process on the computer will connect to ports 32650, 32651, 32660, and 32661.The first ROS 2 process on the computer will connect to ports 32650, 32651, 32662, and 32663.The 53rd ROS 2 process on the computer will connect to ports 32650, 32651, 32766, and 32767.The 54th ROS 2 process on the computer will connect to ports 32650, 32651, 32768, and 32769, running into the ephemeral port range.Thus the maximum number of processes that should be created when using domain ID 101 on Linux is 54.


key: chroma:document
string_value:
Similarly, the maximum number of processes that should be created when using domain ID 232 on Linux is 63, as the maximum port number is 65535.The situation is similar on macOS and Windows, though the numbers are different.

On macOS and Windows, when choosing a domain ID of 166 (the top of the range), the maximum number of ROS 2 processes that can be created on a computer before running into the ephemeral port range is 120.Domain ID to UDP Port CalculatorDomain ID:Participant ID:Discovery Multicast Port:User Multicast Port:Discovery Unicast Port:User Unicast Port:


key: chroma:document
string_value:
Title: URDF

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

Main.html

Section: Installation

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

URDFURDF (Unified Robot Description Format) is a file format for specifying the geometry and organization of robots in ROS.Building a visual robot model from scratchBuilding a movable robot modelAdding physical and collision propertiesUsing Xacro to clean up your codeUsing URDF withrobot_state_publisherGenerating an URDF File


key: chroma:document
string_value:
Title: Monitoring for parameter changes (C++) URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-CPP.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Monitoring for parameter changes (C++)Goal:Learn to use the ParameterEventHandler class to monitor and respond to parameter changes.Tutorial level:IntermediateTime:20 minutesContentsBackgroundPrerequisitesTasks1 Create a package2 Write the C++ node3 Build and runSummaryRelated contentBackgroundOften a node needs to respond to changes to its own parameters or another node’s parameters. The ParameterEventHandler class makes it easy to listen for parameter changes so that your code can respond to them. This tutorial will show you how to use the C++ version of the ParameterEventHandler class to monitor for changes to a node’s own parameters as well as changes to another node’s parameters.PrerequisitesBefore starting this tutorial, you should first complete the following tutorials:Understanding parametersUsing parameters in a class (C++)TasksIn this tutorial, you will create a new package to contain some sample code, write some C++ code to use the ParameterEventHandler class, and test the resulting code.1


key: chroma:document
string_value:
the ParameterEventHandler class, and test the resulting code.1 Create a packageFirst, open a new terminal andsource your ROS 2 installationso thatros2commands will work.Followthese instructionsto create a new workspace namedros2_ws.Recall that packages should be created in thesrcdirectory, not the root of the workspace. So, navigate intoros2_ws/srcand then create a new package there:ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_parameter_event_handler --dependencies rclcppYour terminal will return a message verifying the creation of your packagecpp_parameter_event_handlerand all its necessary files and folders.The--dependenciesargument will automatically add the necessary dependency lines topackage.xmlandCMakeLists.txt.1.1 Updatepackage.xmlBecause you used the--dependenciesoption during package creation, you don’t have to manually add dependencies topackage.xmlorCMakeLists.txt. As always, though, make sure to add the description, maintainer email and name, and license information


key: chroma:document
string_value:
description, maintainer email and name, and license information topackage.xml.<description>C++parametereventsclienttutorial</description><maintaineremail="you@email.com">YourName</maintainer><license>Apache-2.0</license>2 Write the C++ nodeInside theros2_ws/src/cpp_parameter_event_handler/srcdirectory, create a new file calledparameter_event_handler.cppand paste the following code within:#include<memory>#include"rclcpp/rclcpp.hpp"classSampleNodeWithParameters:publicrclcpp::Node{public:SampleNodeWithParameters():Node("node_with_parameters"){this->declare_parameter("an_int_param",0);// Create a parameter subscriber that can be used to monitor parameter changes// (for this node's parameters as well as other nodes' parameters)param_subscriber_=std::make_shared<rclcpp::ParameterEventHandler>(this);// Set a callback for this node's integer parameter, "an_int_param"autocb=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb: Received an update to parameter\"%s\"of type


key: chroma:document
string_value:
Received an update to parameter\"%s\"of type %s:\"%ld\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};cb_handle_=param_subscriber_->add_parameter_callback("an_int_param",cb);}private:std::shared_ptr<rclcpp::ParameterEventHandler>param_subscriber_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle_;};intmain(intargc,char**argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<SampleNodeWithParameters>());rclcpp::shutdown();return0;}2.1 Examine the codeThe first statement,#include<memory>is included so that the code can utilize the std::make_shared template. The next,#include"rclcpp/rclcpp.hpp"is included to allow the code to reference the various functionality provided by the rclcpp interface, including the ParameterEventHandler class.After the class declaration, the code defines a class,SampleNodeWithParameters. The constructor for the class declares an integer parameteran_int_param, with a default value of 0. Next, the code creates aParameterEventHandlerthat will be used to


key: chroma:document
string_value:
the code creates aParameterEventHandlerthat will be used to monitor changes to parameters. Finally, the code creates a lambda function and sets it as the callback to invoke wheneveran_int_paramis updated.NoteIt is very important to save the handle that is returned byadd_parameter_callback; otherwise, the callback will not be properly registered.SampleNodeWithParameters():Node("node_with_parameters"){this->declare_parameter("an_int_param",0);// Create a parameter subscriber that can be used to monitor parameter changes// (for this node's parameters as well as other nodes' parameters)param_subscriber_=std::make_shared<rclcpp::ParameterEventHandler>(this);// Set a callback for this node's integer parameter, "an_int_param"autocb=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb: Received an update to parameter\"%s\"of type %s:\"%ld\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};cb_handle_=param_subscriber_->add_parameter_callback("an_int_param",cb);}Following


key: chroma:document
string_value:
theSampleNodeWithParametersis a typicalmainfunction which initializes ROS, spins the sample node so that it can send and receive messages, and then shuts down after the user enters ^C at the console.intmain(intargc,char**argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<SampleNodeWithParameters>());rclcpp::shutdown();return0;}2.2 Add executableTo build this code, first open theCMakeLists.txtfile and add the following lines of code below the dependencyfind_package(rclcppREQUIRED)add_executable(parameter_event_handler src/parameter_event_handler.cpp)ament_target_dependencies(parameter_event_handler rclcpp)install(TARGETSparameter_event_handlerDESTINATION lib/${PROJECT_NAME})3 Build and runIt’s good practice to runrosdepin the root of your workspace (ros2_ws) to check for missing dependencies before building:LinuxmacOSWindowsrosdep install -i --from-path src --rosdistro $ROS_DISTRO -yrosdep only runs on Linux, so you can skip ahead to next step.rosdep only runs on Linux, so you can skip ahead to


key: chroma:document
string_value:
next step.rosdep only runs on Linux, so you can skip ahead to next step.Navigate back to the root of your workspace,ros2_ws, and build your new package:colcon build --packages-select cpp_parameter_event_handlerOpen a new terminal, navigate toros2_ws, and source the setup files:LinuxmacOSWindows. install/setup.bash. install/setup.bashcall install/setup.batNow run the node:ros2 run cpp_parameter_event_handler parameter_event_handlerThe node is now active and has a single parameter and will print a message whenever this parameter is updated. To test this, open up another terminal and source the ROS setup file as before (. install/setup.bash) and execute the following command:ros2 param set node_with_parameters an_int_param 43The terminal running the node will display a message similar to the following:[INFO] [1606950498.422461764] [node_with_parameters]: cb: Received an update to parameter "an_int_param" of type integer: "43"The callback we set previously in the node has been invoked and has displayed the new


key: chroma:document
string_value:
in the node has been invoked and has displayed the new updated value. You can now terminate the running parameter_event_handler sample using ^C in the terminal.3.1 Monitor changes to another node’s parametersYou can also use the ParameterEventHandler to monitor parameter changes to another node’s parameters. Let’s update the SampleNodeWithParameters class to also monitor for changes to a parameter in another node. We will use the parameter_blackboard demo application to host a double parameter that we will monitor for updates.First update the constructor to add the following code after the existing code:// Now, add a callback to monitor any changes to the remote node's parameter. In this// case, we supply the remote node name.autocb2=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb2: Received an update to parameter\"%s\"of type:


key: chroma:document
string_value:
Received an update to parameter\"%s\"of type: %s:\"%.02lf\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_double());};autoremote_node_name=std::string("parameter_blackboard");autoremote_param_name=std::string("a_double_param");cb_handle2_=param_subscriber_->add_parameter_callback(remote_param_name,cb2,remote_node_name);Then add another member variable,cb_handle2for the additional callback handle:private:std::shared_ptr<rclcpp::ParameterEventHandler>param_subscriber_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle2_;// Add this};In a terminal, navigate back to the root of your workspace,ros2_ws, and build your updated package as before:colcon build --packages-select cpp_parameter_event_handlerThen source the setup files:LinuxmacOSWindows. install/setup.bash. install/setup.bashcall install/setup.batNow, to test monitoring of remote parameters, first run the newly-built parameter_event_handler code:ros2 run cpp_parameter_event_handler


key: chroma:document
string_value:
code:ros2 run cpp_parameter_event_handler parameter_event_handlerNext, from another teminal (with ROS initialized), run the parameter_blackboard demo application, as follows:ros2 run demo_nodes_cpp parameter_blackboardFinally, from a third terminal (with ROS initialized), let’s set a parameter on the parameter_blackboard node:ros2 param set parameter_blackboard a_double_param 3.45Upon executing this command, you should see output in the parameter_event_handler window, indicating that the callback function was invoked upon the parameter update:[INFO] [1606952588.237531933] [node_with_parameters]: cb2: Received an update to parameter "a_double_param" of type: double: "3.45"SummaryYou created a node with a parameter and used the ParameterEventHandler class to set a callback to monitor changes to that parameter. You also used the same class to monitor changes to a remote node. The ParameterEventHandler is a convenient way to monitor for parameter changes so that you can then respond to the updated


key: chroma:document
string_value:
parameter changes so that you can then respond to the updated values.Related contentTo learn how to adapt ROS 1 parameter files for ROS 2, see theMigrating YAML parameter files from ROS 1 to ROS2tutorial.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 pkg create -

build

type ament_cmake -

license Apache

2.0 cpp_parameter_event_handler -

dependencies rclcpp

Language: unknown

<description>C++parametereventsclienttutorial</description><maintaineremail="you@email.com">YourName</maintainer><license>Apache

2.0</license>


key: chroma:document
string_value:
Language: unknown #include<memory>#include"rclcpp/rclcpp.hpp"classSampleNodeWithParameters:publicrclcpp::Node{public:SampleNodeWithParameters():Node("node_with_parameters"){this->declare_parameter("an_int_param",0);// Create a parameter subscriber that can be used to monitor parameter changes// (for this node's parameters as well as other nodes' parameters)param_subscriber_=std::make_shared<rclcpp::ParameterEventHandler>(this);// Set a callback for this node's integer parameter, "an_int_param"autocb=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb: Received an update to parameter\"%s\"of type


key: chroma:document
string_value:
Received an update to parameter\"%s\"of type %s:\"%ld\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};cb_handle_=param_subscriber_->add_parameter_callback("an_int_param",cb);}private:std::shared_ptr<rclcpp::ParameterEventHandler>param_subscriber_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle_;};intmain(intargc,char**argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<SampleNodeWithParameters>());rclcpp::shutdown();return0;}


key: chroma:document
string_value:
Language: unknown SampleNodeWithParameters():Node("node_with_parameters"){this->declare_parameter("an_int_param",0);// Create a parameter subscriber that can be used to monitor parameter changes// (for this node's parameters as well as other nodes' parameters)param_subscriber_=std::make_shared<rclcpp::ParameterEventHandler>(this);// Set a callback for this node's integer parameter, "an_int_param"autocb=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb: Received an update to parameter\"%s\"of type %s:\"%ld\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};cb_handle_=param_subscriber_->add_parameter_callback("an_int_param",cb);}

Language: unknown

intmain(intargc,char*

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

Language: unknown


key: chroma:document
string_value:
Language: unknown

add_executable(parameter_event_handler src/parameter_event_handler.cpp)ament_target_dependencies(parameter_event_handler rclcpp)install(TARGETSparameter_event_handlerDESTINATION lib/${PROJECT_NAME})

Language: unknown

rosdep install

i -

from

path src -

rosdistro $ROS_DISTRO

y

Language: unknown

colcon build -

packages

select cpp_parameter_event_handler

Language: unknown

. install/setup.bash

Language: unknown

. install/setup.bash

Language: unknown

call install/setup.bat

Language: unknown

ros2 run cpp_parameter_event_handler parameter_event_handler

Language: unknown ros2 param set node_with_parameters an_int_param 43

Language: unknown [INFO] [1606950498.422461764] [node_with_parameters]: cb: Received an update to parameter "an_int_param" of type integer: "43"


key: chroma:document
string_value:
Language: unknown // Now, add a callback to monitor any changes to the remote node's parameter. In this// case, we supply the remote node name.autocb2=[this](constrclcpp::Parameter&p){RCLCPP_INFO(this->get_logger(),"cb2: Received an update to parameter\"%s\"of type: %s:\"%.02lf\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_double());};autoremote_node_name=std::string("parameter_blackboard");autoremote_param_name=std::string("a_double_param");cb_handle2_=param_subscriber_->add_parameter_callback(remote_param_name,cb2,remote_node_name);

Language: unknown

private:std::shared_ptr<rclcpp::ParameterEventHandler>param_subscriber_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle_;std::shared_ptr<rclcpp::ParameterCallbackHandle>cb_handle2_;// Add this};

Language: unknown

colcon build -

packages

select cpp_parameter_event_handler

Language: unknown

. install/setup.bash

Language: unknown

. install/setup.bash

Language: unknown

call install/setup.bat

Language: unknown


key: chroma:document
string_value:
Language: unknown

call install/setup.bat

Language: unknown

ros2 run cpp_parameter_event_handler parameter_event_handler

Language: unknown

ros2 run demo_nodes_cpp parameter_blackboard

Language: unknown ros2 param set parameter_blackboard a_double_param 3.45

Language: unknown [INFO] [1606952588.237531933] [node_with_parameters]: cb2: Received an update to parameter "a_double_param" of type: double: "3.45"


key: chroma:document
string_value:
Title: ROS 2 Core Maintainer Guide URL: https://docs.ros.org/en/jazzy/How-To-Guides/Core-maintainer-guide.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
ROS 2 Core Maintainer GuideEach package in the ROS 2 core has one or more maintainers that are responsibile for the general health of the package. This guide gives some information about the responsibilities of a ROS 2 core package maintainer.Table of ContentsReviewsContinuous IntegrationPR builds (https://build.ros2.org/view/Rpr)CI builds (https://ci.ros2.org)Merging Pull RequestsKeeping CI greenMaking releasesSource releaseBinary releaseBackporting to released distributionsResponding to issuesGetting helpReviewsAll incoming code to ROS 2 core repositories must be reviewed. The review is looking for:Suitability in the packageCorrect codeConforms to developer guidelines:Developer GuideCode Style GuideAdds tests for the bug/featureAdds documentation for new featuresClean Continuous Integration runTargets default branch (usually “rolling”)Has at least one approval from a maintainer that is not the authorContinuous IntegrationAll incoming code to ROS 2 core repositories must be run through Continuous


key: chroma:document
string_value:
code to ROS 2 core repositories must be run through Continuous Integration. ROS 2 currently has two separate CI systems, and it is required that PRs pass both of them before merging.PR builds (https://build.ros2.org/view/Rpr)ROS 2 PR (Pull Request) builds run automatically every time a pull request is opened. These builds run a build and test of this repository, and this repository only. This means that it does not build any dependencies, and it also does not build any repositories that depend upon packages in this repository. These builds are good for quick feedback to see if the change passes linters, unit tests, etc. There are two major problems with them:These builds do not work across multiple repositories (so won’t work for adding or changing an API, etc)These tests only run on Linux (they won’t run on macOS or Windows)To address these two problems, there is also the CI builds.CI builds (https://ci.ros2.org)CI builds do not run automatically when a pull request is opened. One of the maintainers of


key: chroma:document
string_value:
when a pull request is opened. One of the maintainers of the repository must manually request that a CI build is done by going tohttps://ci.ros2.org/job/ci_launcher/.By default, running a job in this way will build and run tests for all packages (> 300 currently) on all platforms (Linux, macOS, and Windows). As a full run can take many hours and tie up the CI machines, it is recommended that all runs here restrict the number of packages that are built and tested. This can be accomplished by using the colcon arguments--packages-up-to,--packages-select,--packages-above-and-dependencies,--packages-above, amongst others. See thecolcon documentationfor more examples on the flags that can be used. Further documentation on how to use the CI machinery is available athttps://github.com/ros2/ci/blob/master/CI_BUILDERS.md.Merging Pull RequestsA pull request can be merged if all of the following are true:The DCO bot reports a passing resultThe PR build reports a passing resultThe CI build reports a passing result on


key: chroma:document
string_value:
a passing resultThe CI build reports a passing result on all platformsThe code has been reviewed and approved by at least one maintainerAfter a PR is merged, it will automatically get built with the nextnightlies. It is highly recommended to check the nightlies after merging pull requests to ensure no regressions have occurred.Keeping CI greenThe nightly jobs that run tests are typically much more comprehensive than what is done for individual pull requests. For this reason, there can be regressions that occur in the nightlies that were not seen in the CI jobs. It is a maintainer’s responsibility to check for regressions in their packages at the following locations:https://ci.ros2.org/view/nightlyhttps://ci.ros2.org/view/packaginghttps://build.ros2.org/view/Rcihttps://build.ros2.org/view/RdevFor any problems that are found, new issues and/or pull requests on the relevant repositories should be opened.Making releasesIn order to get new features and bugfixes out to end users, the maintainers must


key: chroma:document
string_value:
features and bugfixes out to end users, the maintainers must periodically do a release of the repository (a release may also be requested on-demand from other maintainers).As outlined in thedeveloper guide, ROS 2 packages follow semver for version numbers.A release, in ROS terms, consists of two distinct steps: making a source release, and then making a binary release.Source releaseA source release creates a changelog and a tag in the relevant repository.The process starts by generating or updating CHANGELOG.rst files with the following command:$catkin_generate_changelogIf one or more packages in the repository don’t have contain CHANGELOG.rst, add the--alloption to populate all of the previous commits for each package. Thecatkin_generate_changelogcommand will simply populate the files with the commit logs from the repository. Since those commit logs aren’t always appropriate for a changelog, it is recommended to edit CHANGELOG.rst and edit it to make it more readable. Once editing is done, it is important


key: chroma:document
string_value:
to make it more readable. Once editing is done, it is important to commit the updated CHANGELOG.rst file to the repository.The next step is to bump the version in the package.xml and the changelog files with the following command:$catkin_prepare_releaseThis command will find all of the packages in the repository, check that the changelogs exist, check that there are no uncommitted local changes, increment the version in the package.xml files, and commit/tag the changes with a bloom-compatible tag. Using this command is the best way to ensure the release versions are consistent and compatible with bloom. By default,catkin_prepare_releasewill bump the patch version of the packages, e.g. 0.1.1 -> 0.1.2 . However, it can also bump the minor or major number, or even have an exact version set. See the help output fromcatkin_prepare_releasefor more information.Assuming the above was successful, a source release has been made.Binary releaseThe next step is to use thebloom-releasecommand to create a binary release.


key: chroma:document
string_value:
is to use thebloom-releasecommand to create a binary release. For full instructions on how to use bloom, please seehttp://wiki.ros.org/bloom. To do a binary release of a repository, run:$bloom-release--track<rosdistro>--rosdistro<rosdistro><repository_name>For instance, to release therclcpprepository to the Jazzy distribution, the command would be:$bloom-release--trackjazzy--rosdistrojazzyrclcppThis command will fetch the release repository, make the necessary changes to make the release, push the changes to the release repository, and finally open a pull request tohttps://github.com/ros/rosdistro.Backporting to released distributionsAll incoming changes should first land on the development branch. Once a change has been merged onto the development branch, it can be considered for backporting to released distributions. However, any backported code must not breakAPIorABIin a released distribution. If a change can be backported without breaking API or ABI, then a new pull request targeting the appropriate


key: chroma:document
string_value:
API or ABI, then a new pull request targeting the appropriate branch should be created. The new pull request should be added to the appropriate distributions project board athttps://github.com/orgs/ros2/projects. The new pull request should have all of the steps run as before, but making sure to target the distribution in question for CI, etc.Responding to issuesPackage maintainers should also look at incoming issues on the repository and triage the problems that users are having.For issues that look like questions, the issue should be closed and the user redirected toRobotics Stack Exchange.If an issue looks like a problem, but is not relevant to this particular repository, it should be moved to the appropriate repository with the GitHub “Transfer issue” button.If the reporter has not provided enough information to determine the cause of the problem, more information should be requested from the reporter.If this is a new feature, tag the issue with “help-wanted”.Any remaining issues should be reproduced,


key: chroma:document
string_value:
with “help-wanted”.Any remaining issues should be reproduced, and determined if they are truly a bug. If it is a bug, fixes are highly appreciated.Getting helpWhile doing maintenance on a package, questions about general procedures or individual issues may come up.For general questions, please follow thecontributing guidelines.For questions on individual issues, please tag the ROS 2 GitHub team (@ros/team), and someone on the team will take a look.


key: chroma:document
string_value:
Code Examples:

Language: unknown

$catkin_generate_changelog

Language: unknown

$catkin_prepare_release

Language: unknown

$bloom

release-

track<rosdistro>-

rosdistro<rosdistro><repository_name>

Language: unknown

$bloom

release-

trackjazzy-

rosdistrojazzyrclcpp


key: chroma:document
string_value:
Title: Code style and language versions URL: https://docs.ros.org/en/jazzy/The-ROS2-Project/Contributing/Code-Style-Language-Versions.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Code style and language versionsTable of ContentsCStandardStyleC++StandardStylePythonVersionStyleCMakeVersionStyleMarkdown / reStructured Text / docblocksStyleIn order to achieve a consistent looking product we will all follow externally (if possible) defined style guidelines for each language. For other things like package layout or documentation layout we will need to come up with our own guidelines, drawing on current, popular styles in use now.Additionally, wherever possible, developers should use integrated tools to allow them to check that these guidelines are followed in their editors. For example, everyone should have a PEP8 checker built into their editor to cut down on review iterations related to style.Also where possible, packages should check style as part of their unit tests to help with the automated detection of style issues (seeament_lint_auto).CStandardWe will target C99.StyleWe will usePython’s PEP7for our C style guide, with some modifications and additions:We will target C99, as we


key: chroma:document
string_value:
with some modifications and additions:We will target C99, as we do not need to support C89 (as PEP7 recommends)rationale: among other things it allows us to use both//and/**/style commentsrationale: C99 is pretty much ubiquitous nowC++ style//comments are allowed(optional) Always place literals on the left-hand side of comparison operators, e.g.0==retinstead ofret==0rationale:ret==0too easily turns intoret=0by accidentoptional because when using-Wall(or equivalent) modern compilers will warn you when this happensAll of the following modifications only apply if we are not writing Python modules:Do not usePy_as a prefix for everythinginstead use a CamelCase version of the package name or other appropriate prefixThe stuff about documentation strings doesn’t applyWe can use thepep7python module for style checking. The editor integration seems slim, we may need to look into automated checking for C in more detail.C++StandardJazzy targets C++17.StyleWe will use theGoogle C++ Style Guide, with some


key: chroma:document
string_value:
C++17.StyleWe will use theGoogle C++ Style Guide, with some modifications:Line LengthOur maximum line length is 100 characters.File ExtensionsHeader files should use the .hpp extension.rationale: Allow tools to determine content of files, C++ or C.Implementation files should use the .cpp extension.rationale: Allow tools to determine content of files, C++ or C.Variable NamingFor global variables use lowercase with underscores prefixed withg_rationale: keep variable naming case consistent across the projectrationale: easy to tell the scope of a variable at a glanceconsistency across languagesFunction and Method NamingGoogle style guide saysCamelCase, but the C++ std library’s style ofsnake_caseis also allowedrationale: ROS 2 core packages currently usesnake_casereason: either an historical oversight or a personal preference that didn’t get checked by the linterreason for not changing: retroactively changing would be too disruptiveother considerations:cpplint.pydoes not check this case (hard to enforce


key: chroma:document
string_value:
not check this case (hard to enforce other than with review)snake_casecan result in more consistency across languagesspecific guidance:for existing projects, prefer the existing stylefor new projects, either is acceptable, but a preference for matching related existing projects is advisedfinal decision is always developer discretionspecial cases like function pointers, callable types, etc. may require bending the rulesNote that classes should still useCamelCaseby defaultAccess ControlDrop requirement for all class members to be private and therefore require accessorsrationale: this is overly constraining for user API designwe should prefer private members, only making them public when they are neededwe should consider using accessors before choosing to allow direct member accesswe should have a good reason for allowing direct member access, other than because it is convenient for usExceptionsExceptions are allowedrationale: this is a new codebase, so the legacy argument doesn’t apply to usrationale: for


key: chroma:document
string_value:
so the legacy argument doesn’t apply to usrationale: for user-facing API’s it is more idiomatic C++ to have exceptionsExceptions in destructors should be explicitly avoidedWe should consider avoiding Exceptions if we intend to wrap the resulting API in Crationale: it will make it easier to wrap in Crationale: most of our dependencies in code we intend to wrap in C do not use exceptions anywaysFunction-like ObjectsNo restrictions on Lambda’s orstd::functionorstd::bindBoostBoost should be avoided unless absolutely required.Comments and Doc CommentsUse///and/***/comments fordocumentationpurposes and//style comments for notes and general commentsClass and Function comments should use///and/***/style commentsrationale: these are recommended for Doxygen and Sphinx in C/C++rationale: mixing/**/and//is convenient for block commenting out code which contains commentsDescriptions of how the code works or notes within classes and functions should use//style commentsPointer Syntax AlignmentUsechar*c;instead


key: chroma:document
string_value:
use//style commentsPointer Syntax AlignmentUsechar*c;instead ofchar*c;orchar*c;because of this scenariochar*c,*d,*e;Class Privacy KeywordsDo not put 1 space beforepublic:,private:, orprotected:, it is more consistent for all indentions to be a multiple of 2rationale: most editors don’t like indentions which are not a multiple of the (soft) tab sizeUse zero spaces beforepublic:,private:, orprotected:, or 2 spacesIf you use 2 spaces before, indent other class statements by 2 additional spacesPrefer zero spaces, i.e.public:,private:, orprotected:in the same column as the classNested TemplatesNever add whitespace to nested templatesPreferset<list<string>>(C++11 feature) toset<list<string>>orset<list<string>>Always Use BracesAlways use braces followingif,else,do,while, andfor, even when the body is a single line.rationale: less opportunity for visual ambiguity and for complications due to use of macros in the bodyOpen Versus Cuddled BracesUse open braces forfunction,class,enum, andstructdefinitions, but


key: chroma:document
string_value:
open braces forfunction,class,enum, andstructdefinitions, but cuddle braces onif,else,while,for, etc…Exception: when anif(orwhile, etc.) condition is long enough to require line-wrapping, then use an open brace (i.e., don’t cuddle).When a function call cannot fit on one line, wrap at the open parenthesis (not in between arguments) and start them on the next line with a 2-space indent.  Continue with the 2-space indent on subsequent lines for more arguments.  (Note that theGoogle style guideis internally contradictory on this point.)Same goes forif(andwhile, etc.) conditions that are too long to fit on one line.ExamplesThis is OK:intmain(intargc,char**argv){if(condition){return0;}else{return1;}}if(this&&that||both){...}// Long condition; open braceif(this&&that||both&&this&&that||both&&this&&that||both&&this&&that){...}// Short function callcall_func(foo,bar);// Long function call; wrap at the open


key: chroma:document
string_value:
callcall_func(foo,bar);// Long function call; wrap at the open parenthesiscall_func(foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar);// Very long function argument; separate it for readabilitycall_func(bang,fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo,bar,bat);This isnotOK:intmain(intargc,char**argv){return0;}if(this&&that||both){...}Use open braces rather than excessive indention, e.g. for distinguishing constructor code from constructor initializer listsThis is OK:ReturnTypeLongClassName::ReallyReallyReallyLongFunctionName(Typepar_name1,// 2 space indentTypepar_name2,Typepar_name3){DoSomething();// 2 space indent...}MyClass::MyClass(intvar):some_var_(var),some_other_var_(var+1){...DoSomething();...}This isnotOK, even weird (the google way?):ReturnTypeLongClassName::ReallyReallyReallyLongFunctionName(Typepar_name1,// 4 space indentTypepar_name2,Typepar_name3){DoSomething();// 2 space


key: chroma:document
string_value:
indentTypepar_name2,Typepar_name3){DoSomething();// 2 space indent...}MyClass::MyClass(intvar):some_var_(var),// 4 space indentsome_other_var_(var+1){// lined up...DoSomething();...}LintersWe check these styles with a combination of Google’scpplint.pyanduncrustify.We provide command line tools with custom configurations:ament_clang_format:configurationament_cpplintament_uncrustify:configurationSome formatters such as ament_uncrustify and ament_clang_format support--reformatoptions to apply changes in place.We also run other tools to detect and eliminate as many warnings as possible. Here’s a non-exhaustive list of additional things we try to do on all of our packages:use compiler flags like-Wall-Wextra-Wpedanticrun static code analysis likecppcheck, which we have integrated inament_cppcheck.PythonVersionWe will target Python 3 for our development.StyleWe will use thePEP8 guidelinesfor code format.We chose the following more precise rule where PEP 8 leaves some freedom:We allow up to 100 characters per


key: chroma:document
string_value:
PEP 8 leaves some freedom:We allow up to 100 characters per line (fifth paragraph).We pick single quotes over double quotes as long as no escaping is necessary.We prefer hanging indents for continuation lines.Tools like the(ament_)pycodestylePython package should be used in unit-test and/or editor integration for checking Python code style.The pycodestyle configuration used in the linter ishere.Integration with editors:atom:https://atom.io/packages/linter-pycodestyleemacs:https://www.emacswiki.org/emacs/PythonProgrammingInEmacsSublime Text:https://sublime.wbond.net/packages/SublimeLinter-flake8vim:https://github.com/nvie/vim-flake8CMakeVersionWe will target CMake 3.8.StyleSince there is not an existing CMake style guide we will define our own:Use lowercase command names (find_package, notFIND_PACKAGE).Usesnake_caseidentifiers (variables, functions, macros).Use emptyelse()andend...()commands.No whitespace before(‘s.Use two spaces of indention, do not use tabs.Do not use aligned indentation for parameters


key: chroma:document
string_value:
do not use tabs.Do not use aligned indentation for parameters of multi-line macro invocations. Use two spaces only.Prefer functions withset(PARENT_SCOPE)to macros.When using macros prefix local variables with_or a reasonable prefix.Markdown / reStructured Text / docblocksStyleThe following rules to format text is intended to increase readability as well as versioning.[.md, .rst only]Each section title should be preceded by one empty line and succeeded by one empty line.Rationale: It expedites to get an overview about the structure when screening the document.[.rst only]In reStructured Text the headings should follow the hierarchy described in theSphinx style guide:#with overline (only once, used for the document title)*with overline=-^"Rationale: A consistent hierarchy expedites getting an idea about the nesting level when screening the document.[.md only]In Markdown the headings should follow the ATX-style described in theMarkdown syntax documentationATX-style headers use 1-6 hash characters (#) at the


key: chroma:document
string_value:
headers use 1-6 hash characters (#) at the start of the line to denote header levels 1-6.A space between the hashes and the header title should be used (such as#Heading1) to make it easier to visually separate them.Justification for the ATX-style preference comes from theGoogle Markdown style guideRationale: ATX-style headers are easier to search and maintain, and make the first two header levels consistent with the other levels.[any]Each sentence must start on a new line.Rationale: For longer paragraphs a single change in the beginning makes the diff unreadable since it carries forward through the whole paragraph.[any]Each sentence can optionally be wrapped to keep each line short.[any]The lines should not have any trailing white spaces.[.md, .rst only]A code block must be preceded and succeeded by an empty line.Rationale: Whitespace is significant only directly before and directly after fenced code blocks. Following these instructions will ensure that highlighting works properly and consistently.[.md, .rst


key: chroma:document
string_value:
that highlighting works properly and consistently.[.md, .rst only]A code block should specify a syntax (e.g.bash).


key: chroma:document
string_value:
Code Examples:

Language: unknown intmain(intargc,char**argv){if(condition){return0;}else{return1;}}if(this&&that||both){...}// Long condition; open braceif(this&&that||both&&this&&that||both&&this&&that||both&&this&&that){...}// Short function callcall_func(foo,bar);// Long function call; wrap at the open parenthesiscall_func(foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo,bar);// Very long function argument; separate it for readabilitycall_func(bang,fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo,bar,bat);

Language: unknown

intmain(intargc,char*

argv){return0;}if(this&&that||both){...}

Language: unknown ReturnTypeLongClassName::ReallyReallyReallyLongFunctionName(Typepar_name1,// 2 space indentTypepar_name2,Typepar_name3){DoSomething();// 2 space indent...}MyClass::MyClass(intvar):some_var_(var),some_other_var_(var+1){...DoSomething();...}


key: chroma:document
string_value:
Language: unknown ReturnTypeLongClassName::ReallyReallyReallyLongFunctionName(Typepar_name1,// 4 space indentTypepar_name2,Typepar_name3){DoSomething();// 2 space indent...}MyClass::MyClass(intvar):some_var_(var),// 4 space indentsome_other_var_(var+1){// lined up...DoSomething();...}


key: chroma:document
string_value:
Title: Development process for a release URL: https://docs.ros.org/en/jazzy/Releases/Release-Process.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Development process for a releaseEach ROS 2 distribution goes through a process of development more than a year long that begins prior to the release of the previous distribution. Below is a high-level view of this development process. There is no specific due date for the items in this process, but in general earlier items should be completed before later items can be completed.For the progress through this process for a specific release, see that release’s documentation page.ItemNotesFind the ROS BossThe “ROS Boss” is the person in charge of shepherding a distribution through the development, release, update, and EOL’ing stages of its life. They are chosen from the internal ROS 2 team at Open Robotics.Run process to choose the distribution nameThe ROS Boss curates the process of choosing the distribution’s name, using input from sources such as the community and potential naming conflicts.Create distribution’s documentation pageEvery distribution has a documentation page that lists its vital statistics,


key: chroma:document
string_value:
has a documentation page that lists its vital statistics, such as planned release date, EOL date, and significant changes since the previous release.Set release timelineThe final weeks leading up to release day (usually, World Turtle Day) are hectic and full of deadlines, such as when to freeze the default RMW implementation. These deadlines must be planned well in advance.Produce roadmapWhile every contributor to ROS has their own planned features for each distribution, we try to maintain an overall roadmap of the new features and significant changes we expect to see in the distribution. The ROS Boss and the leader of the ROS 2 development team at Open Robotics work together with the ROS 2 TSC and other interested parties to produce a roadmap that is achievable in the time available and meets the needs of the ROS community.Announce roadmapThe list of planned features and significant changes is made public, via a GitHub issue that will track the progress on developing each item in the roadmap. Of course,


key: chroma:document
string_value:
the progress on developing each item in the roadmap. Of course, this does not mean that the roadmap is fixed at this point, as development plans can change and we always (and frequently do) welcome new contributions even if they are not on the planned roadmap.Set target platforms and major dependenciesThe target platforms, in terms of operating system, distribution and version, must be set far enough in advance for development work on the infrastructure (such as support in the build farm) to proceed. Similarly, the versions of each major dependency (which Python version, which compiler(s), which version of Eigen, etc.) must also be fixed. This is done via an update toREP-2000.Add platform support to the build farmThe build farm is a critical part of the infrastructure supporting a ROS 2 distribution. It provides continuous integration facilities that help us maintain quality, and it builds the binary packages the community relies on to avoid building ROS 2 and packages from source. If the target platforms


key: chroma:document
string_value:
ROS 2 and packages from source. If the target platforms differ from the previous ROS 2 distribution, then the necessary support must be added to the build farm.Commission logo and related artworkA well-loved part of every ROS 2 distribution (and ROS distribution!) is the logo. The logo is commissioned from a professional artist based on the chosen distribution name. Based on the logo, other artwork such as the turtlesim icon are also produced.Create mailing list for the distributionVital for making critical announcements, a mailing list must be set up to contact people interested in knowing something about the distribution, such as that their package is failing to build into a binary on the build farm.Create test casesAs the development process enters the final few months, testing begins in earnest. The integration test cases that will be used during the final stages of development must be produced and provided to the release team who will be responsible for executing them.Announce upcoming RMW freezeThe RMW


key: chroma:document
string_value:
for executing them.Announce upcoming RMW freezeThe RMW freeze is the point at which the default RMW implementation for the new distribution is feature-frozen. This gives developers a stable target to test their packages with, which is particularly important for the client library developers, who need to know what features of the RMW layer will be available for use by client libraries.Upgrade dependency packagesPackages depended on by ROS but not ROS software and not available in the platform package manager (such as aptitude for Ubuntu), the so-called “vendor packages”, must be updated to the versions specified in REP-2000 (or an appropriate version, for those not listed in REP-2000). This is particularly important on Windows.Create a detailed release planPlanning for the final two months of the development process is performed. This produces a detailed test plan, timelines of when certain packages must be available, and so on. It enables the finding of dependencies between steps in the release process and


key: chroma:document
string_value:
of dependencies between steps in the release process and finding people to perform each of those steps.Freeze RMWThe RMW implementation is now feature-frozen. In theory, it can now be exhaustively tested to ensure it is working correctly by release day.Announce upcoming overall freezeThe next freeze after freezing the RMW implementation is to freeze the distribution as a whole. This is the point at which the core ROS packages become feature-frozen, giving developers of non-core packages a stable target to test their packages against, and giving distribution testers something to test that won’t change right after they’ve tested it.Freeze distributionFrom this point on, no new features can be added to any of the core ROS packages. Only bug fixes for the (inevitable) bugs found during the intensive integration test phases of development can be incorporated into the codebase. This means that Rolling Ridley is effectively frozen, temperarily.Announce upcoming branchThe branching of the new ROS 2 distribution from


key: chroma:document
string_value:
upcoming branchThe branching of the new ROS 2 distribution from Rolling Ridley is an important moment. It is worth preparing for.Announce upcoming betaWhen the distribution enters beta, it is ready for wider testing by the ROS community. This beta happens soon after the distribution is branched from Rolling Ridely.Branch from Rolling RidleyThe new ROS 2 distribution is created by making a new branch from Rolling Ridley. In effect, the new distribution is born at this point in time. Meanwhile, Rolling Ridley is free from the development process and can roll on into the future, once again receiving new features.Add distribution to CIThe continuous integration system is updated to allow building using the new distribution’s branches and core ROS packages. This means that package developers can run CI for their packages against the new distribution, rather than Rolling Ridley.Begin building interim testing tarballsThe elite team of testers who will put the new distribution through its paces need something to


key: chroma:document
string_value:
put the new distribution through its paces need something to test without compiling ROS 2 from source constantly. The build farm is used to produce a set of tarballs containing the distribution at a point in time for the testers to test.Add distribution documentationDetailed documentation about the distribution, such as the significant changes since the previous distribution, is added to the ROS 2 documentation site.Announce betaThe beta release of the distribution is made and the ROS community as a whole is invited to contribute to testing it (for those who aren’t already doing so). At this point, the more testers the better, because the distribution needs to be put through as wide a range of scenarios as possible to find bugs before the release.Final release preparationsAs the new distribution enters is absolutely-completely-everything-frozen phase, the final preparations are made for the release. These include things like producing binary packages using the build farm so there will be something to


key: chroma:document
string_value:
packages using the build farm so there will be something to release.ReleaseThe big day, which if all goes to plan coincides with World Turtle Day on May 23rd. The distribution’s binary packages are made available in the release repository, and an announcement is made. Parties are held and the ROS 2 development team takes a well-earned break.


key: chroma:document
string_value:
Title: Running Tests in ROS 2 from the Command Line URL: https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Testing/CLI.html Section: Installation --------------------------------------------------------------------------------

Running Tests in ROS 2 from the Command LineBuild and run your testsTo compile and run the tests, simply run thetestverb fromcolcon.colcon test --ctest-args tests [package_selection_args](wherepackage_selection_argsare optional package selection arguments forcolconto limit which packages are built and run)Sourcing the workspacebefore testing should not be necessary.colcontestmakes sure that the tests run with the right environment, have access to their dependencies, etc.Examine Test ResultsTo see the results, simply run thetest-resultverb fromcolcon.colcon test-result --allTo see the exact test cases which fail, use the--verboseflag:colcon test-result --all --verboseDebugging tests with GDBFor detailed guidance on debugging tests using GDB, refer to theGDB Tutorial.


key: chroma:document
string_value:
Code Examples:

Language: unknown

colcon test -

ctest

args tests [package_selection_args]

Language: unknown

colcon test

result -

all

Language: unknown

colcon test

result -

all -

verbose


key: chroma:document
string_value:
Title: Windows (source)

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

Development

Setup.html

Section: Installation

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


key: chroma:document
string_value:
Windows (source)Table of ContentsSystem requirementsLanguage supportSystem setupInstall ChocolateyInstall PythonInstall Visual C++ RedistributablesInstall OpenSSLInstall Visual StudioInstall OpenCVInstall dependenciesInstall miscellaneous prerequisitesInstall Qt5RQt dependenciesInstall additional prerequisites from ChocolateyInstall Python prerequisitesBuild ROS 2Get ROS 2 codeInstall additional RMW implementations (optional)Build the code in the workspaceSetup environmentTry some examplesNext stepsExtra stuff for Debug modeStay up to dateTroubleshootUninstallThis guide is about how to setup a development environment for ROS 2 on Windows.System requirementsOnly Windows 10 is supported.Language supportMake sure you have a locale which supportsUTF-8. For example, for a Chinese-language Windows 10 installation, you may need to install anEnglish language pack.System setupInstall ChocolateyChocolatey is a package manager for Windows, install it by following their installation


key: chroma:document
string_value:
manager for Windows, install it by following their installation instructions:https://chocolatey.org/installYou’ll use Chocolatey to install some other developer tools.Install PythonOpen a Command Prompt and type the following to install Python via Chocolatey:chocoinstall-ypython--version3.8.3NoteChocolatey will install Python inC:\Python38, and the rest of the installation expects it to be there. If you’ve installed Python somewhere else, you must copy or link it to that location.Install Visual C++ RedistributablesOpen a Command Prompt and type the following to install them via Chocolatey:chocoinstall-yvcredist2013vcredist140Install OpenSSLOpen a Command Prompt and type the following to install OpenSSL via Chocolatey:chocoinstall-yopenssl--version1.1.1.2100This command sets an environment variable that persists over sessions:setx/mOPENSSL_CONF"C:\Program Files\OpenSSL-Win64\bin\openssl.cfg"You will need to append the OpenSSL-Win64 bin folder to your PATH. You can do this by clicking the Windows icon,


key: chroma:document
string_value:
to your PATH. You can do this by clicking the Windows icon, typing “Environment Variables”, then clicking on “Edit the system environment variables”. In the resulting dialog, click “Environment Variables”, then click “Path” on the bottom pane, finally click “Edit” and add the path below.C:\ProgramFiles\OpenSSL-Win64\bin\Install Visual StudioInstall Visual Studio 2019.If you already have a paid version of Visual Studio 2019 (Professional, Enterprise), skip this step.Microsoft provides a free of charge version of Visual Studio 2019, named Community, which can be used to build applications that use ROS 2.You can download the installer directly through this link.Make sure that the Visual C++ features are installed.An easy way to make sure they’re installed is to select theDesktopdevelopmentwithC++workflow during the install.Make sure that no C++ CMake tools are installed by unselecting them in the list of components to be installed.Install OpenCVSome of the examples require OpenCV to be installed.You can


key: chroma:document
string_value:
of the examples require OpenCV to be installed.You can download a precompiled version of OpenCV 3.4.6 fromhttps://github.com/ros2/ros2/releases/download/opencv-archives/opencv-3.4.6-vc16.VS2019.zip.Assuming you unpacked it toC:\opencv, type the following on a Command Prompt (requires Admin privileges):setx/mOpenCV_DIRC:\opencvSince you are using a precompiled ROS version, we have to tell it where to find the OpenCV libraries. You have to extend thePATHvariable toC:\opencv\x64\vc16\bin.Install dependenciesThere are a few dependencies not available in the Chocolatey package database. In order to ease the manual installation process, we provide the necessary Chocolatey packages.As some chocolatey packages rely on it, we start by installing CMakechocoinstall-ycmakeYou will need to append the CMake bin folderC:\ProgramFiles\CMake\binto your PATH.Please download these packages fromthisGitHub repository.asio.1.12.1.nupkgbullet.3.17.nupkgcunit.2.1.3.nupkgeigen.3.3.4.nupkgtinyxml2.6.0.0.nupkgOnce these packages are


key: chroma:document
string_value:
in an administratorcmd.exewindow set these environment variables. The commands below assume you installed it to the default location ofC:\Qt.setx/mQt5_DIRC:\Qt\Qt5.12.12\5.12.12\msvc2017_64 setx/mQT_QPA_PLATFORM_PLUGIN_PATHC:\Qt\Qt5.12.12\5.12.12\msvc2017_64\plugins\platformsNoteThis path might change based on the installed MSVC version, the directory Qt was installed to, and the version of Qt installed.RQt dependenciesTo run rqt_graph you need todownloadand installGraphviz. The installer will ask if to add graphviz to PATH, choose to either add it to the current user or all users.Install additional prerequisites from Chocolateychocoinstall-ycppcheckcurlgitwinflexbison3You will need to append the Git cmd folderC:\ProgramFiles\Git\cmdto the PATH (you can do this by clicking the Windows icon, typing “Environment Variables”, then clicking on “Edit the system environment variables”. In the resulting dialog, click “Environment Variables”, the click “Path” on the bottom pane, then click “Edit” and add the


key: chroma:document
string_value:
click “Path” on the bottom pane, then click “Edit” and add the path).Install Python prerequisitesInstall additional Python dependencies:pipinstall-Ucolcon-common-extensionscoverageflake8flake8-blind-exceptflake8-builtinsflake8-class-newlineflake8-comprehensionsflake8-deprecatedflake8-docstringsflake8-import-orderflake8-quotesmockmypy==0.931pep8pydocstylepytestpytest-covpytest-mockpytest-repeatpytest-rerunfailurespytest-runnervcstoolBuild ROS 2Get ROS 2 codeNow that we have the development tools we can get the ROS 2 source code.First setup a development folder, for exampleC:\jazzy:NoteIt is very important that the chosen path is short, due to the short default Windows path limits (260 characters). To allow longer paths, seehttps://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry.md\jazzy\srccd\jazzyGet theros2.reposfile which defines the repositories to clone from:vcsimport--inputhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repossrcInstall additional RMW


key: chroma:document
string_value:
additional RMW implementations (optional)The default middleware that ROS 2 uses isFastDDS, but the middleware (RMW) can be replaced at build or runtime. See theguideon how to work with multiple RMWs.Build the code in the workspaceTo build ROS 2 you will need a Visual Studio Command Prompt (“x64 Native Tools Command Prompt for VS 2019”) running as Administrator.To build the\jazzyfolder tree:colconbuild--merge-installNoteWe’re using--merge-installhere to avoid aPATHvariable that is too long at the end of the build. If you’re adapting these instructions to build a smaller workspace then you might be able to use the default behavior which is isolated install, i.e. where each package is installed to a different folder.NoteIf you are doing a debug build usepython_dpath\to\colcon_executablecolcon. SeeExtra stuff for debug modefor more info on running Python code in debug builds on Windows.Setup environmentStart a command shell and source the ROS 2 setup file to set up the


key: chroma:document
string_value:
a command shell and source the ROS 2 setup file to set up the workspace:callC:\jazzy\install\local_setup.batThis will automatically set up the environment for any DDS vendors that support was built for.It is normal that the previous command, if nothing else went wrong, outputs “The system cannot find the path specified.” exactly once.Try some examplesNote that the first time you run any executable you will have to allow access to the network through a Windows Firewall popup.You can run the tests using this command:colcontest--merge-installNote--merge-installshould only be used if it was also used in the build step.Afterwards you can get a summary of the tests using this command:colcontest-resultTo run the examples, first open a clean newcmd.exeand set up the workspace by sourcing thelocal_setup.batfile. Then, run a C++talker:callinstall\local_setup.bat ros2rundemo_nodes_cpptalkerIn a separate shell you can do the same, but instead run a Pythonlistener:callinstall\local_setup.bat


key: chroma:document
string_value:
but instead run a Pythonlistener:callinstall\local_setup.bat ros2rundemo_nodes_pylistenerYou should see thetalkersaying that it’sPublishingmessages and thelistenersayingIheardthose messages. This verifies both the C++ and Python APIs are working properly. Hooray!NoteIt is not recommended to build in the same cmd prompt that you’ve sourced thelocal_setup.bat.Next stepsContinue with thetutorials and demosto configure your environment, create your own workspace and packages, and learn ROS 2 core concepts.Extra stuff for Debug modeIf you want to be able to run all the tests in Debug mode, you’ll need to install a few more things:To be able to extract the Python source tarball, you can use PeaZip:chocoinstall-ypeazipYou’ll also need SVN, since some of the Python source-build dependencies are checked out via SVN:chocoinstall-ysvnhgYou’ll need to quit and restart the command prompt after installing the above.Get and extract the Python 3.8.3 source from


key: chroma:document
string_value:
the above.Get and extract the Python 3.8.3 source from thetgz:https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgzTo keep these instructions concise, please extract it toC:\dev\Python-3.8.3Now, build the Python source in debug mode from a Visual Studio command prompt:cdC:\dev\Python-3.8.3\PCbuild get_externals.bat build.bat-px64-dFinally, copy the build products into the Python38 installation directories, next to the Release-mode Python executable and DLL’s:cdC:\dev\Python-3.8.3\PCbuild\amd64 copypython_d.exeC:\Python38/Y copypython38_d.dllC:\Python38/Y copypython3_d.dllC:\Python38/Y copypython38_d.libC:\Python38\libs/Y copypython3_d.libC:\Python38\libs/Y copysqlite3_d.dllC:\Python38\DLLs/Yfor%Iin(*_d.pyd)docopy%IC:\Python38\DLLs/YNow, from a fresh command prompt, make sure thatpython_dworks:python_d-c"import _ctypes ; import coverage"Once you have verified the operation ofpython_d, it is necessary to reinstall a few dependencies with the debug-enabled


key: chroma:document
string_value:
to reinstall a few dependencies with the debug-enabled libraries:python_d-mpipinstall--force-reinstallhttps://github.com/ros2/ros2/releases/download/numpy-archives/numpy-1.18.4-cp38-cp38d-win_amd64.whl python_d-mpipinstall--force-reinstallhttps://github.com/ros2/ros2/releases/download/lxml-archives/lxml-4.5.1-cp38-cp38d-win_amd64.whlTo verify the installation of these dependencies:python_d-c"from lxml import etree ; import numpy"When you wish to return to building release binaries, it is necessary to uninstall the debug variants and use the release variants:python-mpipuninstallnumpylxml python-mpipinstallnumpylxmlTo create executables python scripts(.exe), python_d should be used to invoke colconpython_dpath\to\colcon_executablebuildHooray, you’re done!Stay up to dateSeeMaintain source checkoutto periodically refresh your source installation.TroubleshootTroubleshooting techniques can be foundhere.UninstallIf you installed your workspace with colcon as instructed above, “uninstalling” could be just a


key: chroma:document
string_value:
with colcon as instructed above, “uninstalling” could be just a matter of opening a new terminal and not sourcing the workspace’ssetupfile. This way, your environment will behave as though there is no Jazzy install on your system.If you’re also trying to free up space, you can delete the entire workspace directory with:rmdir/s/q\ros2_jazzy


key: chroma:document
string_value:
Code Examples:

Language: unknown

chocoinstall

ypython-

version3.8.3

Language: unknown

chocoinstall

yvcredist2013vcredist140

Language: unknown

chocoinstall

yopenssl-

version1.1.1.2100

Language: unknown

setx/mOPENSSL_CONF"C:\Program Files\OpenSSL

Win64\bin\openssl.cfg"

Language: unknown

setx/mOpenCV_DIRC:\opencv

Language: unknown

chocoinstall

ycmake

Language: unknown

chocoinstall

y

s<PATH\TO\DOWNLOADS\>asiocuniteigentinyxml2bullet

Language: unknown

python

mpipinstall

Upipsetuptools==59.6.0

Language: unknown

python

mpipinstall

Ucatkin_pkgcryptographyempyimportlib

metadatajsonschemalark==1.1.1lxmlmatplotlibnetifacesnumpyopencv

pythonPyQt5pillowpsutilpycairopydotpyparsing==2.4.7pytestpyyamlrosdistro

Language: unknown

setx/mQt5_DIRC:\Qt\Qt5.12.12\5.12.12\msvc2017_64

setx/mQT_QPA_PLATFORM_PLUGIN_PATHC:\Qt\Qt5.12.12\5.12.12\msvc2017_64\plugins\platforms

Language: unknown

chocoinstall

ycppcheckcurlgitwinflexbison3

Language: unknown

pipinstall

Ucolcon

common


key: chroma:document
string_value:
Language: unknown

pipinstall

Ucolcon

common

extensionscoverageflake8flake8

blind

exceptflake8

builtinsflake8

class

newlineflake8

comprehensionsflake8

deprecatedflake8

docstringsflake8

import

orderflake8

quotesmockmypy==0.931pep8pydocstylepytestpytest

covpytest

mockpytest

repeatpytest

rerunfailurespytest

runnervcstool

Language: unknown

md\jazzy\srccd\jazzy

Language: unknown

vcsimport-

inputhttps://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repossrc

Language: unknown

colconbuild-

merge

install

Language: unknown

callC:\jazzy\install\local_setup.bat

Language: unknown

colcontest-

merge

install

Language: unknown

colcontest

result

Language: unknown

callinstall\local_setup.bat

ros2rundemo_nodes_cpptalker

Language: unknown

callinstall\local_setup.bat

ros2rundemo_nodes_pylistener

Language: unknown

chocoinstall

ypeazip

Language: unknown

chocoinstall

ysvnhg

Language: unknown

cdC:\dev\Python

3.8.3\PCbuild

get_externals.bat

build.bat

px64

d

Language: unknown


key: chroma:document
string_value:
get_externals.bat

build.bat

px64

d

Language: unknown

cdC:\dev\Python

3.8.3\PCbuild\amd64

copypython_d.exeC:\Python38/Y

copypython38_d.dllC:\Python38/Y

copypython3_d.dllC:\Python38/Y

copypython38_d.libC:\Python38\libs/Y

copypython3_d.libC:\Python38\libs/Y

copysqlite3_d.dllC:\Python38\DLLs/Yfor%Iin(

_d.pyd)docopy%IC:\Python38\DLLs/Y

Language: unknown python_d-c"import _ctypes ; import coverage"

Language: unknown

python_d

mpipinstall-

force

reinstallhttps://github.com/ros2/ros2/releases/download/numpy

archives/numpy

1.18.4

cp38

cp38d

win_amd64.whl

python_d

mpipinstall-

force

reinstallhttps://github.com/ros2/ros2/releases/download/lxml

archives/lxml

4.5.1

cp38

cp38d

win_amd64.whl

Language: unknown python_d-c"from lxml import etree ; import numpy"

Language: unknown

python

mpipuninstallnumpylxml

python

mpipinstallnumpylxml

Language: unknown

python_dpath\to\colcon_executablebuild

Language: unknown

rmdir/s/q\ros2_jazzy


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

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

CLI

Tools/Understanding

ROS2

Nodes/Understanding

ROS2

Nodes.html

Section: Installation

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


key: chroma:document
string_value:
Understanding nodesGoal:Learn about the function of nodes in ROS 2, and the tools to interact with them.Tutorial level:BeginnerTime:10 minutesContentsBackground1 The ROS 2 graph2 Nodes in ROS 2PrerequisitesTasks1 ros2 run2 ros2 node list3 ros2 node infoSummaryNext stepsRelated contentBackground1 The ROS 2 graphOver the next few tutorials, you will learn about a series of core ROS 2 concepts that make up what is referred to as the “ROS (2) graph”.The ROS graph is a network of ROS 2 elements processing data together at the same time. It encompasses all executables and the connections between them if you were to map them all out and visualize them.2 Nodes in ROS 2Each node in ROS should be responsible for a single, modular purpose, e.g. controlling the wheel motors or publishing the sensor data from a laser range-finder. Each node can send and receive data from other nodes via topics, services, actions, or parameters.A full robotic system is comprised of many nodes working in concert. In ROS 2, a single


key: chroma:document
string_value:
comprised of many nodes working in concert. In ROS 2, a single executable (C++ program, Python program, etc.) can contain one or more nodes.PrerequisitesTheprevious tutorialshows you how to install theturtlesimpackage used here.As always, don’t forget to source ROS 2 inevery new terminal you open.Tasks1 ros2 runThe commandros2runlaunches an executable from a package.ros2 run <package_name> <executable_name>To run turtlesim, open a new terminal, and enter the following command:ros2 run turtlesim turtlesim_nodeThe turtlesim window will open, as you saw in theprevious tutorial.Here, the package name isturtlesimand the executable name isturtlesim_node.We still don’t know the node name, however. You can find node names by usingros2nodelist2 ros2 node listros2nodelistwill show you the names of all running nodes. This is especially useful when you want to interact with a node, or when you have a system running many nodes and need to keep track of them.Open a new terminal while turtlesim is still running in the


key: chroma:document
string_value:
a new terminal while turtlesim is still running in the other one, and enter the following command:ros2 node listThe terminal will return the node name:/turtlesimOpen another new terminal and start the teleop node with the command:ros2 run turtlesim turtle_teleop_keyHere, we are referring to theturtlesimpackage again, but this time we target the executable namedturtle_teleop_key.Return to the terminal where you ranros2nodelistand run it again. You will now see the names of two active nodes:/turtlesim/teleop_turtle2.1 RemappingRemappingallows you to reassign default node properties, like node name, topic names, service names, etc., to custom values. In the last tutorial, you used remapping onturtle_teleop_keyto change the cmd_vel topic and targetturtle2.Now, let’s reassign the name of our/turtlesimnode. In a new terminal, run the following command:ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtleSince you’re callingros2runon turtlesim again, another turtlesim window will open. However,


key: chroma:document
string_value:
turtlesim again, another turtlesim window will open. However, now if you return to the terminal where you ranros2nodelist, and run it again, you will see three node names:/my_turtle/turtlesim/teleop_turtle3 ros2 node infoNow that you know the names of your nodes, you can access more information about them with:ros2 node info <node_name>To examine your latest node,my_turtle, run the following command:ros2 node info /my_turtleros2nodeinforeturns a list of subscribers, publishers, services, and actions. i.e. the ROS graph connections that interact with that node. The output should look like this:/my_turtleSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEvent/turtle1/cmd_vel: geometry_msgs/msg/TwistPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/color_sensor: turtlesim/msg/Color/turtle1/pose: turtlesim/msg/PoseService Servers:/clear: std_srvs/srv/Empty/kill: turtlesim/srv/Kill/my_turtle/describe_parameters:


key: chroma:document
string_value:
turtlesim/srv/Kill/my_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters/my_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/my_turtle/get_parameters: rcl_interfaces/srv/GetParameters/my_turtle/list_parameters: rcl_interfaces/srv/ListParameters/my_turtle/set_parameters: rcl_interfaces/srv/SetParameters/my_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically/reset: std_srvs/srv/Empty/spawn: turtlesim/srv/Spawn/turtle1/set_pen: turtlesim/srv/SetPen/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute/turtle1/teleport_relative: turtlesim/srv/TeleportRelativeService Clients:Action Servers:/turtle1/rotate_absolute: turtlesim/action/RotateAbsoluteAction Clients:Now try running the same command on the/teleop_turtlenode, and see how its connections differ frommy_turtle.You will learn more about the ROS graph connection concepts including the message types in the upcoming tutorials.SummaryA node is a fundamental ROS 2 element that serves a single, modular


key: chroma:document
string_value:
is a fundamental ROS 2 element that serves a single, modular purpose in a robotics system.In this tutorial, you utilized nodes created in theturtlesimpackage by running the executablesturtlesim_nodeandturtle_teleop_key.You learned how to useros2nodelistto discover active node names andros2nodeinfoto introspect a single node. These tools are vital to understanding the flow of data in a complex, real-world robot system.Next stepsNow that you understand nodes in ROS 2, you can move on to thetopics tutorial. Topics are one of the communication types that connects nodes.Related contentTheConceptspage adds some more detail to the concept of nodes.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 run <package_name> <executable_name>

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 node list

Language: unknown

/turtlesim

Language: unknown

ros2 run turtlesim turtle_teleop_key

Language: unknown

/turtlesim/teleop_turtle

Language: unknown ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle

Language: unknown

/my_turtle/turtlesim/teleop_turtle

Language: unknown

ros2 node info <node_name>

Language: unknown

ros2 node info /my_turtle


key: chroma:document
string_value:
Language: unknown /my_turtleSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEvent/turtle1/cmd_vel: geometry_msgs/msg/TwistPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/color_sensor: turtlesim/msg/Color/turtle1/pose: turtlesim/msg/PoseService Servers:/clear: std_srvs/srv/Empty/kill: turtlesim/srv/Kill/my_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters/my_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/my_turtle/get_parameters: rcl_interfaces/srv/GetParameters/my_turtle/list_parameters: rcl_interfaces/srv/ListParameters/my_turtle/set_parameters: rcl_interfaces/srv/SetParameters/my_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically/reset: std_srvs/srv/Empty/spawn: turtlesim/srv/Spawn/turtle1/set_pen: turtlesim/srv/SetPen/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute/turtle1/teleport_relative: turtlesim/srv/TeleportRelativeService Clients:Action


key: chroma:document
string_value:
turtlesim/srv/TeleportRelativeService Clients:Action Servers:/turtle1/rotate_absolute: turtlesim/action/RotateAbsoluteAction Clients:


key: chroma:document
string_value:
Title: Beginner: CLI tools

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

CLI

Tools.html

Section: Installation

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

Beginner: CLI toolsConfiguring environmentUsingturtlesim,ros2, andrqtUnderstanding nodesUnderstanding topicsUnderstanding servicesUnderstanding parametersUnderstanding actionsUsingrqt_consoleto view logsLaunching nodesRecording and playing back data


key: chroma:document
string_value:
Title: Using event handlers

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

Event

Handlers.html

Section: Installation

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


key: chroma:document
string_value:
Using event handlersGoal:Learn about event handlers in ROS 2 launch filesTutorial level:IntermediateTime:15 minutesTable of ContentsBackgroundPrerequisitesUsing event handlers1 Event handlers example launch fileBuild the packageLaunching exampleDocumentationSummaryBackgroundLaunch in ROS 2 is a system that executes and manages user-defined processes. It is responsible for monitoring the state of processes it launched, as well as reporting and reacting to changes in the state of those processes. These changes are called events and can be handled by registering an event handler with the launch system. Event handlers can be registered for specific events and can be useful for monitoring the state of processes. Additionally, they can be used to define a complex set of rules which can be used to dynamically modify the launch file.This tutorial shows usage examples of event handlers in ROS 2 launch files.PrerequisitesThis tutorial uses theturtlesimpackage. This tutorial also assumes you havecreated a new


key: chroma:document
string_value:
This tutorial also assumes you havecreated a new packageof build typeament_pythoncalledlaunch_tutorial.This tutorial extends the code shown in theUsing substitutions in launch filestutorial.Using event handlers1 Event handlers example launch fileCreate a new file calledexample_event_handlers_launch.pyfile in thelaunchfolder of


key: chroma:document
string_value:
thelaunch_tutorialpackage.fromlaunch_ros.actionsimportNodefromlaunchimportLaunchDescriptionfromlaunch.actionsimport(DeclareLaunchArgument,EmitEvent,ExecuteProcess,LogInfo,RegisterEventHandler,TimerAction)fromlaunch.conditionsimportIfConditionfromlaunch.event_handlersimport(OnExecutionComplete,OnProcessExit,OnProcessIO,OnProcessStart,OnShutdown)fromlaunch.eventsimportShutdownfromlaunch.substitutionsimport(EnvironmentVariable,FindExecutable,LaunchConfiguration,LocalSubstitution,PythonExpression)defgenerate_launch_description():turtlesim_ns=LaunchConfiguration('turtlesim_ns')use_provided_red=LaunchConfiguration('use_provided_red')new_background_r=LaunchConfiguration('new_background_r')turtlesim_ns_launch_arg=DeclareLaunchArgument('turtlesim_ns',default_value='turtlesim1')use_provided_red_launch_arg=DeclareLaunchArgument('use_provided_red',default_value='False')new_background_r_launch_arg=DeclareLaunchArgument('new_background_r',default_value='200')turtlesim_node=Node(package='turtlesim',namespace=turtlesim_ns,e


key: chroma:document
string_value:
turtlesim_node=Node(package='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node',name='sim')spawn_turtle=ExecuteProcess(cmd=[[FindExecutable(name='ros2'),'


key: chroma:document
string_value:
service call ',turtlesim_ns,'/spawn ','turtlesim/srv/Spawn ','"{x: 2, y: 2, theta: 0.2}"']],shell=True)change_background_r=ExecuteProcess(cmd=[[FindExecutable(name='ros2'),' param set ',turtlesim_ns,'/sim background_r ','120']],shell=True)change_background_r_conditioned=ExecuteProcess(condition=IfCondition(PythonExpression([new_background_r,' == 200',' and ',use_provided_red])),cmd=[[FindExecutable(name='ros2'),' param set ',turtlesim_ns,'/sim background_r ',new_background_r]],shell=True)returnLaunchDescription([turtlesim_ns_launch_arg,use_provided_red_launch_arg,new_background_r_launch_arg,turtlesim_node,RegisterEventHandler(OnProcessStart(target_action=turtlesim_node,on_start=[LogInfo(msg='Turtlesim started, spawning turtle'),spawn_turtle])),RegisterEventHandler(OnProcessIO(target_action=spawn_turtle,on_stdout=lambdaevent:LogInfo(msg='Spawn request says "{}"'.format(event.text.decode().strip())))),RegisterEventHandler(OnExecutionComplete(target_action=spawn_turtle,on_completion=[LogInfo(msg='Spawn


key: chroma:document
string_value:
finished'),change_background_r,TimerAction(period=2.0,actions=[change_background_r_conditioned],)])),RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(msg=(EnvironmentVariable(name='USER'),' closed the turtlesim window')),EmitEvent(event=Shutdown(reason='Window closed'))])),RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(msg=['Launch was asked to shutdown: ',LocalSubstitution('event.reason')])])),])RegisterEventHandleractions for theOnProcessStart,OnProcessIO,OnExecutionComplete,OnProcessExit, andOnShutdownevents were defined in the launch description.TheOnProcessStartevent handler is used to register a callback function that is executed when the turtlesim node starts. It logs a message to the console and executes thespawn_turtleaction when the turtlesim node starts.RegisterEventHandler(OnProcessStart(target_action=turtlesim_node,on_start=[LogInfo(msg='Turtlesim started, spawning turtle'),spawn_turtle])),TheOnProcessIOevent handler is used to register a callback function


key: chroma:document
string_value:
handler is used to register a callback function that is executed when thespawn_turtleaction writes to its standard output. It logs the result of the spawn request.RegisterEventHandler(OnProcessIO(target_action=spawn_turtle,on_stdout=lambdaevent:LogInfo(msg='Spawn request says "{}"'.format(event.text.decode().strip())))),TheOnExecutionCompleteevent handler is used to register a callback function that is executed when thespawn_turtleaction completes. It logs a message to the console and executes thechange_background_randchange_background_r_conditionedactions when the spawn action completes.RegisterEventHandler(OnExecutionComplete(target_action=spawn_turtle,on_completion=[LogInfo(msg='Spawn finished'),change_background_r,TimerAction(period=2.0,actions=[change_background_r_conditioned],)])),TheOnProcessExitevent handler is used to register a callback function that is executed when the turtlesim node exits. It logs a message to the console and executes theEmitEventaction to emit aShutdownevent when the turtlesim


key: chroma:document
string_value:
theEmitEventaction to emit aShutdownevent when the turtlesim node exits. It means that the launch process will shutdown when the turtlesim window is closed.RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(msg=(EnvironmentVariable(name='USER'),' closed the turtlesim window')),EmitEvent(event=Shutdown(reason='Window closed'))])),Finally, theOnShutdownevent handler is used to register a callback function that is executed when the launch file is asked to shutdown. It logs a message to the console why the launch file is asked to shutdown. It logs the message with a reason for shutdown like the closure of turtlesim window orctrl-csignal made by the user.RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(msg=['Launch was asked to shutdown: ',LocalSubstitution('event.reason')])])),Build the packageGo to the root of the workspace, and build the package:colcon buildAlso remember to source the workspace after building.Launching exampleNow you can launch


key: chroma:document
string_value:
workspace after building.Launching exampleNow you can launch theexample_event_handlers_launch.pyfile using theros2launchcommand.ros2 launch launch_tutorial example_event_handlers_launch.py turtlesim_ns:='turtlesim3' use_provided_red:='True' new_background_r:=200This will do the following:Start a turtlesim node with a blue backgroundSpawn the second turtleChange the color to purpleChange the color to pink after two seconds if the providedbackground_rargument is200anduse_provided_redargument isTrueShutdown the launch file when the turtlesim window is closedAdditionally, it will log messages to the console when:The turtlesim node startsThe spawn action is executedThechange_background_raction is executedThechange_background_r_conditionedaction is executedThe turtlesim node exitsThe launch process is asked to shutdown.DocumentationThe launch documentationprovides detailed information about available event handlers.SummaryIn this tutorial, you learned about using event handlers in launch files. You learned


key: chroma:document
string_value:
learned about using event handlers in launch files. You learned about their syntax and usage examples to define a complex set of rules to dynamically modify launch files.


key: chroma:document
string_value:
fromlaunch_ros.actionsimportNodefromlaunchimportLaunchDescriptionfromlaunch.actionsimport(DeclareLaunchArgument,EmitEvent,ExecuteProcess,LogInfo,RegisterEventHandler,TimerAction)fromlaunch.conditionsimportIfConditionfromlaunch.event_handlersimport(OnExecutionComplete,OnProcessExit,OnProcessIO,OnProcessStart,OnShutdown)fromlaunch.eventsimportShutdownfromlaunch.substitutionsimport(EnvironmentVariable,FindExecutable,LaunchConfiguration,LocalSubstitution,PythonExpression)defgenerate_launch_description():turtlesim_ns=LaunchConfiguration('turtlesim_ns')use_provided_red=LaunchConfiguration('use_provided_red')new_background_r=LaunchConfiguration('new_background_r')turtlesim_ns_launch_arg=DeclareLaunchArgument('turtlesim_ns',default_value='turtlesim1')use_provided_red_launch_arg=DeclareLaunchArgument('use_provided_red',default_value='False')new_background_r_launch_arg=DeclareLaunchArgument('new_background_r',default_value='200')turtlesim_node=Node(package='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node'


key: chroma:document
string_value:
e='turtlesim',namespace=turtlesim_ns,executable='turtlesim_node',name='sim')spawn_turtle=ExecuteProcess(cmd=[[FindExecutable(name='ros2'),'


key: chroma:document
string_value:
finished'),change_background_r,TimerAction(period=2.0,actions=[change_background_r_conditioned],)])),RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(msg=(EnvironmentVariable(name='USER'),' closed the turtlesim window')),EmitEvent(event=Shutdown(reason='Window closed'))])),RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(msg=['Launch was asked to shutdown: ',LocalSubstitution('event.reason')])])),])


key: chroma:document
string_value:
Language: unknown

RegisterEventHandler(OnProcessStart(target_action=turtlesim_node,on_start=[LogInfo(msg='Turtlesim started, spawning turtle'),spawn_turtle])),

Language: unknown

RegisterEventHandler(OnProcessIO(target_action=spawn_turtle,on_stdout=lambdaevent:LogInfo(msg='Spawn request says "{}"'.format(event.text.decode().strip())))),

Language: unknown

RegisterEventHandler(OnExecutionComplete(target_action=spawn_turtle,on_completion=[LogInfo(msg='Spawn finished'),change_background_r,TimerAction(period=2.0,actions=[change_background_r_conditioned],)])),

Language: unknown RegisterEventHandler(OnProcessExit(target_action=turtlesim_node,on_exit=[LogInfo(msg=(EnvironmentVariable(name='USER'),' closed the turtlesim window')),EmitEvent(event=Shutdown(reason='Window closed'))])),

Language: unknown RegisterEventHandler(OnShutdown(on_shutdown=[LogInfo(msg=['Launch was asked to shutdown: ',LocalSubstitution('event.reason')])])),

Language: unknown

colcon build


key: chroma:document
string_value:
Language: unknown

colcon build

Language: unknown ros2 launch launch_tutorial example_event_handlers_launch.py turtlesim_ns:='turtlesim3' use_provided_red:='True' new_background_r:=200


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

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

CLI

Tools/Understanding

ROS2

Actions/Understanding

ROS2

Actions.html

Section: Installation

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


key: chroma:document
string_value:
Understanding actionsGoal:Introspect actions in ROS 2.Tutorial level:BeginnerTime:15 minutesContentsBackgroundPrerequisitesTasks1 Setup2 Use actions3 ros2 node info4 ros2 action list5 ros2 action type6 ros2 action info7 ros2 interface show8 ros2 action send_goalSummaryNext stepsRelated contentBackgroundActions are one of the communication types in ROS 2 and are intended for long running tasks. They consist of three parts: a goal, feedback, and a result.Actions are built on topics and services. Their functionality is similar to services, except actions can be canceled. They also provide steady feedback, as opposed to services which return a single response.Actions use a client-server model, similar to the publisher-subscriber model (described in thetopics tutorial). An “action client” node sends a goal to an “action server” node that acknowledges the goal and returns a stream of feedback and a result.PrerequisitesThis tutorial builds off concepts, likenodesandtopics, covered in previous tutorials.This


key: chroma:document
string_value:
likenodesandtopics, covered in previous tutorials.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 Use actionsWhen you launch the/teleop_turtlenode, you will see the following message in your terminal:Use arrow keys to move the turtle.Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.Let’s focus on the second line, which corresponds to an action. (The first instruction corresponds to the “cmd_vel” topic, discussed previously in thetopics tutorial.)Notice that the letter keysG|B|V|C|D|E|R|Tform a “box” around theFkey on a US QWERTY keyboard (if you are not using a QWERTY keyboard, seethis linkto follow along). Each key’s position aroundFcorresponds to that orientation in turtlesim. For example, theEwill rotate


key: chroma:document
string_value:
to that orientation in turtlesim. For example, theEwill rotate the turtle’s orientation to the upper left corner.Pay attention to the terminal where the/turtlesimnode is running. Each time you press one of these keys, you are sending a goal to an action server that is part of the/turtlesimnode. The goal is to rotate the turtle to face a particular direction. A message relaying the result of the goal should display once the turtle completes its rotation:[INFO] [turtlesim]: Rotation goal completed successfullyTheFkey will cancel a goal mid-execution.Try pressing theCkey, and then pressing theFkey before the turtle can complete its rotation. In the terminal where the/turtlesimnode is running, you will see the message:[INFO] [turtlesim]: Rotation goal canceledNot only can the client-side (your input in the teleop) stop a goal, but the server-side (the/turtlesimnode) can as well. When the server-side chooses to stop processing a goal, it is said to “abort” the goal.Try hitting theDkey, then theGkey before the


key: chroma:document
string_value:
“abort” the goal.Try hitting theDkey, then theGkey before the first rotation can complete. In the terminal where the/turtlesimnode is running, you will see the message:[WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goalThis action server chose to abort the first goal because it got a new one. It could have chosen something else, like reject the new goal or execute the second goal after the first one finished. Don’t assume every action server will choose to abort the current goal when it gets a new one.3 ros2 node infoTo see the list of actions a node provides,/turtlesimin this case, open a new terminal and run the command:ros2 node info /turtlesimWhich will return a list of/turtlesim’s subscribers, publishers, services, action servers and action clients:/turtlesimSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEvent/turtle1/cmd_vel: geometry_msgs/msg/TwistPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout:


key: chroma:document
string_value:
rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/color_sensor: turtlesim/msg/Color/turtle1/pose: turtlesim/msg/PoseService Servers:/clear: std_srvs/srv/Empty/kill: turtlesim/srv/Kill/reset: std_srvs/srv/Empty/spawn: turtlesim/srv/Spawn/turtle1/set_pen: turtlesim/srv/SetPen/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute/turtle1/teleport_relative: turtlesim/srv/TeleportRelative/turtlesim/describe_parameters: rcl_interfaces/srv/DescribeParameters/turtlesim/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/turtlesim/get_parameters: rcl_interfaces/srv/GetParameters/turtlesim/list_parameters: rcl_interfaces/srv/ListParameters/turtlesim/set_parameters: rcl_interfaces/srv/SetParameters/turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomicallyService Clients:Action Servers:/turtle1/rotate_absolute: turtlesim/action/RotateAbsoluteAction Clients:Notice that the/turtle1/rotate_absoluteaction for/turtlesimis underActionServers. This means/turtlesimresponds


key: chroma:document
string_value:
underActionServers. This means/turtlesimresponds to and provides feedback for the/turtle1/rotate_absoluteaction.The/teleop_turtlenode has the name/turtle1/rotate_absoluteunderActionClientsmeaning that it sends goals for that action name. To see that, run:ros2 node info /teleop_turtleWhich will return:/teleop_turtleSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEventPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/cmd_vel: geometry_msgs/msg/TwistService Servers:/teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters/teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters/teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters/teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters/teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomicallyService Clients:Action Servers:Action Clients:/turtle1/rotate_absolute:


key: chroma:document
string_value:
Clients:Action Servers:Action Clients:/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute4 ros2 action listTo identify all the actions in the ROS graph, run the command:ros2 action listWhich will return:/turtle1/rotate_absoluteThis is the only action in the ROS graph right now. It controls the turtle’s rotation, as you saw earlier. You also already know that there is one action client (part of/teleop_turtle) and one action server (part of/turtlesim) for this action from using theros2nodeinfo<node_name>command.4.1 ros2 action list -tActions have types, similar to topics and services. To find/turtle1/rotate_absolute’s type, run the command:ros2 action list -tWhich will return:/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]In brackets to the right of each action name (in this case only/turtle1/rotate_absolute) is the action type,turtlesim/action/RotateAbsolute. You will need this when you want to execute an action from the command line or from code.5 ros2 action typeIf you want to check the


key: chroma:document
string_value:
line or from code.5 ros2 action typeIf you want to check the action type for the action, run the command:ros2 action type /turtle1/rotate_absoluteWhich will return:turtlesim/action/RotateAbsolute6 ros2 action infoYou can further introspect the/turtle1/rotate_absoluteaction with the command:ros2 action info /turtle1/rotate_absoluteWhich will returnAction: /turtle1/rotate_absoluteAction clients: 1/teleop_turtleAction servers: 1/turtlesimThis tells us what we learned earlier from runningros2nodeinfoon each node: The/teleop_turtlenode has an action client and the/turtlesimnode has an action server for the/turtle1/rotate_absoluteaction.7 ros2 interface showOne more piece of information you will need before sending or executing an action goal yourself is the structure of the action type.Recall that you identified/turtle1/rotate_absolute’s type when running the commandros2actionlist-t. Enter the following command with the action type in your terminal:ros2 interface show turtlesim/action/RotateAbsoluteWhich will


key: chroma:document
string_value:
interface show turtlesim/action/RotateAbsoluteWhich will return:#Thedesiredheadinginradiansfloat32 theta---#Theangulardisplacementinradianstothestartingpositionfloat32 delta---#Theremainingrotationinradiansfloat32 remainingThe section of this message above the first---is the structure (data type and name) of the goal request. The next section is the structure of the result. The last section is the structure of the feedback.8 ros2 action send_goalNow let’s send an action goal from the command line with the following syntax:ros2 action send_goal <action_name> <action_type> <values><values>need to be in YAML format.Keep an eye on the turtlesim window, and enter the following command into your terminal:ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"You should see the turtle rotating, as well as the following message in your terminal:Waiting for an action server to become available...Sending goal:theta: 1.57Goal accepted with ID:


key: chroma:document
string_value:
available...Sending goal:theta: 1.57Goal accepted with ID: f8db8f44410849eaa93d3feb747dd444Result:delta: -1.568000316619873Goal finished with status: SUCCEEDEDAll goals have a unique ID, shown in the return message. You can also see the result, a field with the namedelta, which is the displacement to the starting position.To see the feedback of this goal, add--feedbackto theros2actionsend_goalcommand:ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedbackYour terminal will return the message:Sending goal:theta: -1.57Goal accepted with ID: e6092c831f994afda92f0086f220da27Feedback:remaining: -3.1268222332000732Feedback:remaining: -3.1108222007751465…Result:delta: 3.1200008392333984Goal finished with status: SUCCEEDEDYou will continue to receive feedback, the remaining radians, until the goal is complete.SummaryActions are like services that allow you to execute long running tasks, provide regular feedback, and are cancelable.A robot system would likely use


key: chroma:document
string_value:
feedback, and are cancelable.A robot system would likely use actions for navigation. An action goal could tell a robot to travel to a position. While the robot navigates to the position, it can send updates along the way (i.e. feedback), and then a final result message once it’s reached its destination.Turtlesim has an action server that action clients can send goals to for rotating turtles. In this tutorial, you introspected that action,/turtle1/rotate_absolute, to get a better idea of what actions are and how they work.Next stepsNow you’ve covered all of the core ROS 2 concepts. The last few tutorials in this set will introduce you to some tools and techniques that will make using ROS 2 easier, starting withUsing rqt_console to view logs.Related contentYou can read more about the design decisions behind actions in ROS 2here.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtle_teleop_key

Language: unknown Use arrow keys to move the turtle.Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.

Language: unknown [INFO] [turtlesim]: Rotation goal completed successfully

Language: unknown [INFO] [turtlesim]: Rotation goal canceled

Language: unknown [WARN] [turtlesim]: Rotation goal received before a previous goal finished. Aborting previous goal

Language: unknown

ros2 node info /turtlesim


key: chroma:document
string_value:
Language: unknown /turtlesimSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEvent/turtle1/cmd_vel: geometry_msgs/msg/TwistPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/color_sensor: turtlesim/msg/Color/turtle1/pose: turtlesim/msg/PoseService Servers:/clear: std_srvs/srv/Empty/kill: turtlesim/srv/Kill/reset: std_srvs/srv/Empty/spawn: turtlesim/srv/Spawn/turtle1/set_pen: turtlesim/srv/SetPen/turtle1/teleport_absolute: turtlesim/srv/TeleportAbsolute/turtle1/teleport_relative: turtlesim/srv/TeleportRelative/turtlesim/describe_parameters: rcl_interfaces/srv/DescribeParameters/turtlesim/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/turtlesim/get_parameters: rcl_interfaces/srv/GetParameters/turtlesim/list_parameters: rcl_interfaces/srv/ListParameters/turtlesim/set_parameters: rcl_interfaces/srv/SetParameters/turtlesim/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomicallyService Clients:Action


key: chroma:document
string_value:
Language: unknown

ros2 node info /teleop_turtle

Language: unknown /teleop_turtleSubscribers:/parameter_events: rcl_interfaces/msg/ParameterEventPublishers:/parameter_events: rcl_interfaces/msg/ParameterEvent/rosout: rcl_interfaces/msg/Log/turtle1/cmd_vel: geometry_msgs/msg/TwistService Servers:/teleop_turtle/describe_parameters: rcl_interfaces/srv/DescribeParameters/teleop_turtle/get_parameter_types: rcl_interfaces/srv/GetParameterTypes/teleop_turtle/get_parameters: rcl_interfaces/srv/GetParameters/teleop_turtle/list_parameters: rcl_interfaces/srv/ListParameters/teleop_turtle/set_parameters: rcl_interfaces/srv/SetParameters/teleop_turtle/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomicallyService Clients:Action Servers:Action Clients:/turtle1/rotate_absolute: turtlesim/action/RotateAbsolute

Language: unknown

ros2 action list

Language: unknown

/turtle1/rotate_absolute

Language: unknown

ros2 action list

t

Language: unknown

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]


key: chroma:document
string_value:
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

Language: unknown

ros2 action type /turtle1/rotate_absolute

Language: unknown

turtlesim/action/RotateAbsolute

Language: unknown

ros2 action info /turtle1/rotate_absolute

Language: unknown Action: /turtle1/rotate_absoluteAction clients: 1/teleop_turtleAction servers: 1/turtlesim

Language: unknown

ros2 interface show turtlesim/action/RotateAbsolute

Language: unknown

#Thedesiredheadinginradiansfloat32 theta--

#Theangulardisplacementinradianstothestartingpositionfloat32 delta--

#Theremainingrotationinradiansfloat32 remaining

Language: unknown ros2 action send_goal <action_name> <action_type> <values>

Language: unknown ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"

Language: unknown Waiting for an action server to become available...Sending goal:theta: 1.57Goal accepted with ID: f8db8f44410849eaa93d3feb747dd444Result:delta: -1.568000316619873Goal finished with status: SUCCEEDED


key: chroma:document
string_value:
Language: unknown ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback

Language: unknown Sending goal:theta: -1.57Goal accepted with ID: e6092c831f994afda92f0086f220da27Feedback:remaining: -3.1268222332000732Feedback:remaining: -3.1108222007751465…Result:delta: 3.1200008392333984Goal finished with status: SUCCEEDED


key: chroma:document
string_value:
Title: Cross

compilation

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

Cross

Compilation.html

Section: Installation

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


key: chroma:document
string_value:
Cross-compilationTable of ContentsOverviewHow does it work ?AlternativesOverviewOpen Robotics provides pre-built ROS 2 packages for multiple platforms, but a number of developers still rely oncross-compilationfor different reasons such as:The development machine does not match the target system.Tuning the build for specific core architecture (e.g. setting -mcpu=cortex-a53 -mfpu=neon-fp-armv8 when building for Raspberry Pi3).Targeting a file system other than the ones supported by the pre-built images released by Open Robotics.How does it work ?Cross-compiling simple software (e.g. no dependencies on external libraries) is relatively simple and only requiring a cross-compiler toolchain to be used instead of the native toolchain.There are a number of factors which make this process more complex:The software being built must support the target architecture. Architecture specific code must be properly isolated and enabled during the build according to the target architecture. Examples include assembly


key: chroma:document
string_value:
according to the target architecture. Examples include assembly code.All dependencies (e.g. libraries) must be present, either as pre-built or cross-compiled packages, before the target software using them is cross-compiled.When building software stacks (as opposed to standalone software) using build tools (e.g. colcon), it is expected that the build tool provides a mechanism to allow the developer to enable cross-compilation on the underlying build system used by each piece of software in the stack.AlternativesAn alternative to cross-compilation is tobuild multi-platform Docker imagesusingdockerbuildx.


key: chroma:document
string_value:
Title: Recording a bag from a node (Python) URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-Py.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Recording a bag from a node (Python)Goal:Record data from your own Python node to a bag.Tutorial level:AdvancedTime:20 minutesContentsBackgroundPrerequisitesTasks1 Create a package2 Write the Python node3 Build and run4 Record synthetic data from a node5 Record synthetic data from an executableSummaryBackgroundrosbag2doesn’t just provide theros2bagcommand line tool. It also provides a Python API for reading from and writing to a bag from your own source code. This allows you to subscribe to a topic and save the received data to a bag at the same time as performing any other processing of your choice on that data. You may do this, for example, to save data from a topic and the result of processing that data without needing to send the processed data over a topic just to record it. Because any data can be recorded in a bag, it is also possible to save data generated by another source than a topic, such as synthetic data for training sets. This is useful, for example, for quickly generating a bag that


key: chroma:document
string_value:
This is useful, for example, for quickly generating a bag that contains a large number of samples spread over a long playback time.PrerequisitesYou should have therosbag2packages installed as part of your regular ROS 2 setup.If you’ve installed from deb packages on Linux, it may be installed by default. If it is not, you can install it using this command.sudo apt install ros-jazzy-rosbag2This tutorial discusses using ROS 2 bags, including from the terminal. You should have already completed thebasic ROS 2 bag tutorial.Tasks1 Create a packageOpen a new terminal andsource your ROS 2 installationso thatros2commands will work.Followthese instructionsto create a new workspace namedros2_ws.Navigate into theros2_ws/srcdirectory and create a new package:ros2 pkg create --build-type ament_python --license Apache-2.0 bag_recorder_nodes_py --dependencies rclpy rosbag2_py example_interfaces std_msgsYour terminal will return a message verifying the creation of your packagebag_recorder_nodes_pyand all its necessary


key: chroma:document
string_value:
of your packagebag_recorder_nodes_pyand all its necessary files and folders. The--dependenciesargument will automatically add the necessary dependency lines to thepackage.xml. In this case, the package will use therosbag2_pypackage as well as therclpypackage. A dependency on theexample_interfacespackage is also required for message definitions.1.1 Updatepackage.xmlandsetup.pyBecause you used the--dependenciesoption during package creation, you don’t have to manually add dependencies topackage.xml. As always, though, make sure to add the description, maintainer email and name, and license information topackage.xml.<description>Pythonbagwritingtutorial</description><maintaineremail="you@email.com">YourName</maintainer><license>Apache-2.0</license>Also be sure to add this information to thesetup.pyfile as well.maintainer='Your Name',maintainer_email='you@email.com',description='Python bag writing tutorial',license='Apache-2.0',2 Write the Python nodeInside


key: chroma:document
string_value:
tutorial',license='Apache-2.0',2 Write the Python nodeInside theros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_pydirectory, create a new file calledsimple_bag_recorder.pyand paste the following code into


key: chroma:document
string_value:
calledsimple_bag_recorder.pyand paste the following code into it.importrclpyfromrclpy.nodeimportNodefromrclpy.serializationimportserialize_messagefromstd_msgs.msgimportStringimportrosbag2_pyclassSimpleBagRecorder(Node):def__init__(self):super().__init__('simple_bag_recorder')self.writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='my_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='chatter',type='std_msgs/msg/String',serialization_format='cdr')self.writer.create_topic(topic_info)self.subscription=self.create_subscription(String,'chatter',self.topic_callback,10)self.subscriptiondeftopic_callback(self,msg):self.writer.write('chatter',serialize_message(msg),self.get_clock().now().nanoseconds)defmain(args=None):rclpy.init(args=args)sbr=SimpleBagRecorder()rclpy.spin(sbr)rclpy.shutdown()if__name__=='__main__':main()2.1 Examine the


key: chroma:document
string_value:
Examine the codeTheimportstatements at the top are the package dependencies. Note the importation of therosbag2_pypackage for the functions and structures necessary to work with bag files.In the class constructor, we begin by creating the writer object that we will use to write to the bag. We are creating aSequentialWriter, which writes messages into the bag in the order they are received. Other writers with different behaviours may be available inrosbag2.self.writer=rosbag2_py.SequentialWriter()Now that we have a writer object, we can open the bag using it. We specify the URI of the bag to create and the format (mcap), leaving other options at their defaults. The default conversion options are used, which will perform no conversion and store the messages in the serialization format they are received in.storage_options=rosbag2_py._storage.StorageOptions(uri='my_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)Next, we need


key: chroma:document
string_value:
we need to tell the writer about the topics we wish to store. This is done by creating aTopicMetadataobject and registering it with the writer. This object specifies the topic name, topic data type, and serialization format used.topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='chatter',type='std_msgs/msg/String',serialization_format='cdr')self.writer.create_topic(topic_info)With the writer now set up to record data we pass to it, we create a subscription and specify a callback for it. We will write data to the bag in the callback.self.subscription=self.create_subscription(String,'chatter',self.topic_callback,10)self.subscriptionThe callback receives the message in unserialized form (as is standard for therclpyAPI) and passes the message to the writer, specifying the topic that the data is for and the timestamp to record with the message. However, the writer requires serialized messages to store in the bag. This means that we need to serialize the data before passing it to the writer. For this reason,


key: chroma:document
string_value:
the data before passing it to the writer. For this reason, we callserialize_message()and pass the result of that to the writer, rather than passing in the message directly.deftopic_callback(self,msg):self.writer.write('chatter',serialize_message(msg),self.get_clock().now().nanoseconds)The file finishes with themainfunction used to create an instance of the node and start ROS processing it.defmain(args=None):rclpy.init(args=args)sbr=SimpleBagRecorder()rclpy.spin(sbr)rclpy.shutdown()2.2 Add entry pointOpen thesetup.pyfile in thebag_recorder_nodes_pypackage and add an entry point for your node.entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main',],},3 Build and runNavigate back to the root of your workspace,ros2_ws, and build your new package.LinuxmacOSWindowscolcon build --packages-select bag_recorder_nodes_pycolcon build --packages-select bag_recorder_nodes_pycolcon build --merge-install --packages-select bag_recorder_nodes_pyOpen a new terminal, navigate


key: chroma:document
string_value:
bag_recorder_nodes_pyOpen a new terminal, navigate toros2_ws, and source the setup files.LinuxmacOSWindowssource install/setup.bashsource install/setup.bashcall install/setup.batNow run the node:ros2 run bag_recorder_nodes_py simple_bag_recorderOpen a second terminal and run thetalkerexample node.ros2 run demo_nodes_cpp talkerThis will start publishing data on thechattertopic. As the bag-writing node receives this data, it will write it to themy_bagbag. If themy_bagdirectory already exists, you must first delete it before running thesimple_bag_recordernode. This is becauserosbag2will not overwrite existing bags by default, and so the destination directory cannot exist.Terminate both nodes. Then, in one terminal start thelistenerexample node.ros2 run demo_nodes_cpp listenerIn the other terminal, useros2bagto play the bag recorded by your node.ros2 bag play my_bagYou will see the messages from the bag being received by thelistenernode.If you wish to run the bag-writing node again, you will first need to delete


key: chroma:document
string_value:
run the bag-writing node again, you will first need to delete themy_bagdirectory.4 Record synthetic data from a nodeAny data can be recorded into a bag, not just data received over a topic. A common use case for writing to a bag from your own node is to generate and store synthetic data. In this section you will learn how to write a node that generates some data and stores it in a bag. We will demonstrate two approaches for doing this. The first uses a node with a timer; this is the approach that you would use if your data generation is external to the node, such as reading data directly from hardware (e.g. a camera). The second approach does not use a node; this is the approach you can use when you do not need to use any functionality from the ROS infrastructure.4.1 Write a Python nodeInside theros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_pydirectory, create a new file calleddata_generator_node.pyand paste the following code into


key: chroma:document
string_value:
paste the following code into it.importrclpyfromrclpy.nodeimportNodefromrclpy.serializationimportserialize_messagefromexample_interfaces.msgimportInt32importrosbag2_pyclassDataGeneratorNode(Node):def__init__(self):super().__init__('data_generator_node')self.data=Int32()self.data.data=0self.writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='timed_synthetic_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')self.writer.create_topic(topic_info)self.timer=self.create_timer(1,self.timer_callback)deftimer_callback(self):self.writer.write('synthetic',serialize_message(self.data),self.get_clock().now().nanoseconds)self.data.data+=1defmain(args=None):rclpy.init(args=args)dgn=DataGeneratorNode()rclpy.spin(dgn)rclpy.shutdown()if__name__=='__main__':main()4.2 Examine


key: chroma:document
string_value:
Examine the codeMuch of this code is the same as the first example. The important differences are described here.First, the name of the bag is changed.storage_options=rosbag2_py._storage.StorageOptions(uri='timed_synthetic_bag',storage_id='mcap')The name of the topic is also changed, as is the data type stored.topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')self.writer.create_topic(topic_info)Rather than a subscription to a topic, this node has a timer. The timer fires with a one-second period, and calls the given member function when it does.self.timer=self.create_timer(1,self.timer_callback)Within the timer callback, we generate (or otherwise obtain, e.g. read from a serial port connected to some hardware) the data we wish to store in the bag. As with the previous example, the data is not yet serialized, so we must serialize it before passing it to the


key: chroma:document
string_value:
serialized, so we must serialize it before passing it to the writer.self.writer.write('synthetic',serialize_message(self.data),self.get_clock().now().nanoseconds)4.3 Add executableOpen thesetup.pyfile in thebag_recorder_nodes_pypackage and add an entry point for your node.entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main','data_generator_node = bag_recorder_nodes_py.data_generator_node:main',],},4.4 Build and runNavigate back to the root of your workspace,ros2_ws, and build your package.LinuxmacOSWindowscolcon build --packages-select bag_recorder_nodes_pycolcon build --packages-select bag_recorder_nodes_pycolcon build --merge-install --packages-select bag_recorder_nodes_pyOpen a new terminal, navigate toros2_ws, and source the setup files.LinuxmacOSWindowssource install/setup.bashsource install/setup.bashcall install/setup.batIf thetimed_synthetic_bagdirectory already exists, you must first delete it before running the node.Now run the node:ros2 run


key: chroma:document
string_value:
delete it before running the node.Now run the node:ros2 run bag_recorder_nodes_py data_generator_nodeWait for 30 seconds or so, then terminate the node withctrl-c. Next, play back the created bag.ros2 bag play timed_synthetic_bagOpen a second terminal and echo the/synthetictopic.ros2 topic echo /syntheticYou will see the data that was generated and stored in the bag printed to the console at a rate of one message per second.5 Record synthetic data from an executableNow that you can create a bag that stores data from a source other than a topic, you will learn how to generate and record synthetic data from a non-node executable. The advantage of this approach is simpler code and rapid creation of a large quantity of data.5.1 Write a Python executableInside theros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_pydirectory, create a new file calleddata_generator_executable.pyand paste the following code into


key: chroma:document
string_value:
paste the following code into it.fromrclpy.clockimportClockfromrclpy.durationimportDurationfromrclpy.serializationimportserialize_messagefromexample_interfaces.msgimportInt32importrosbag2_pydefmain(args=None):writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='big_synthetic_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')writer.create_topic(topic_info)time_stamp=Clock().now()foriiinrange(0,100):data=Int32()data.data=iiwriter.write('synthetic',serialize_message(data),time_stamp.nanoseconds)time_stamp+=Duration(seconds=1)if__name__=='__main__':main()5.2 Examine the codeA comparison of this sample and the previous sample will reveal that they are not that different. The only significant difference is the use of a for loop to drive the data generation rather than


key: chroma:document
string_value:
the use of a for loop to drive the data generation rather than a timer.Notice that we are also now generating time stamps for the data rather than relying on the current system time for each sample. The time stamp can be any value you need it to be. The data will be played back at the rate given by these time stamps, so this is a useful way to control the default playback speed of the samples. Notice also that while the gap between each sample is a full second in time, this executable does not need to wait a second between each sample. This allows us to generate a lot of data covering a wide span of time in much less time than playback will take.time_stamp=Clock().now()foriiinrange(0,100):data=Int32()data.data=iiwriter.write('synthetic',serialize_message(data),time_stamp.nanoseconds)time_stamp+=Duration(seconds=1)5.3 Add executableOpen thesetup.pyfile in thebag_recorder_nodes_pypackage and add an entry point for your node.entry_points={'console_scripts':['simple_bag_recorder =


key: chroma:document
string_value:
node.entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main','data_generator_node = bag_recorder_nodes_py.data_generator_node:main','data_generator_executable = bag_recorder_nodes_py.data_generator_executable:main',],},5.4 Build and runNavigate back to the root of your workspace,ros2_ws, and build your package.LinuxmacOSWindowscolcon build --packages-select bag_recorder_nodes_pycolcon build --packages-select bag_recorder_nodes_pycolcon build --merge-install --packages-select bag_recorder_nodes_pyOpen a terminal, navigate toros2_ws, and source the setup files.LinuxmacOSWindowssource install/setup.bashsource install/setup.bashcall install/setup.batIf thebig_synthetic_bagdirectory already exists, you must first delete it before running the executable.Now run the executable:ros2 run bag_recorder_nodes_py data_generator_executableNote that the executable runs and finishes very quickly.Now play back the created bag.ros2 bag play big_synthetic_bagOpen a second


key: chroma:document
string_value:
the created bag.ros2 bag play big_synthetic_bagOpen a second terminal and echo the/synthetictopic.ros2 topic echo /syntheticYou will see the data that was generated and stored in the bag printed to the console at a rate of one message per second. Even though the bag was generated rapidly it is still played back at the rate the time stamps indicate.SummaryYou created a node that records data it receives on a topic into a bag. You tested recording a bag using the node, and verified the data was recorded by playing back the bag. This approach can be used to record a bag with additional data than it received over a topic, for example with results obtained from processing the received data. You then went on to create a node and an executable to generate synthetic data and store it in a bag. The latter approaches are useful especially for generating synthetic data that can be used, for example, as training sets.


key: chroma:document
string_value:
Code Examples:

Language: unknown

sudo apt install ros

jazzy

rosbag2

Language: unknown ros2 pkg create --build-type ament_python --license Apache-2.0 bag_recorder_nodes_py --dependencies rclpy rosbag2_py example_interfaces std_msgs

Language: unknown

<description>Pythonbagwritingtutorial</description><maintaineremail="you@email.com">YourName</maintainer><license>Apache

2.0</license>

Language: unknown maintainer='Your Name',maintainer_email='you@email.com',description='Python bag writing tutorial',license='Apache-2.0',

Language: unknown


key: chroma:document
string_value:
Language: unknown

importrclpyfromrclpy.nodeimportNodefromrclpy.serializationimportserialize_messagefromstd_msgs.msgimportStringimportrosbag2_pyclassSimpleBagRecorder(Node):def__init__(self):super().__init__('simple_bag_recorder')self.writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='my_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='chatter',type='std_msgs/msg/String',serialization_format='cdr')self.writer.create_topic(topic_info)self.subscription=self.create_subscription(String,'chatter',self.topic_callback,10)self.subscriptiondeftopic_callback(self,msg):self.writer.write('chatter',serialize_message(msg),self.get_clock().now().nanoseconds)defmain(args=None):rclpy.init(args=args)sbr=SimpleBagRecorder()rclpy.spin(sbr)rclpy.shutdown()if__name__=='__main__':main()

Language: unknown

self.writer=rosbag2_py.SequentialWriter()


key: chroma:document
string_value:
Language: unknown

self.writer=rosbag2_py.SequentialWriter()

Language: unknown

storage_options=rosbag2_py._storage.StorageOptions(uri='my_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)

Language: unknown

topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='chatter',type='std_msgs/msg/String',serialization_format='cdr')self.writer.create_topic(topic_info)

Language: unknown

self.subscription=self.create_subscription(String,'chatter',self.topic_callback,10)self.subscription

Language: unknown

deftopic_callback(self,msg):self.writer.write('chatter',serialize_message(msg),self.get_clock().now().nanoseconds)

Language: unknown

defmain(args=None):rclpy.init(args=args)sbr=SimpleBagRecorder()rclpy.spin(sbr)rclpy.shutdown()

Language: unknown

entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main',],},

Language: unknown

colcon build -

packages


key: chroma:document
string_value:
Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

merge

install -

packages

select bag_recorder_nodes_py

Language: unknown

source install/setup.bash

Language: unknown

source install/setup.bash

Language: unknown

call install/setup.bat

Language: unknown

ros2 run bag_recorder_nodes_py simple_bag_recorder

Language: unknown

ros2 run demo_nodes_cpp talker

Language: unknown

ros2 run demo_nodes_cpp listener

Language: unknown

ros2 bag play my_bag

Language: unknown


key: chroma:document
string_value:
ros2 bag play my_bag

Language: unknown

importrclpyfromrclpy.nodeimportNodefromrclpy.serializationimportserialize_messagefromexample_interfaces.msgimportInt32importrosbag2_pyclassDataGeneratorNode(Node):def__init__(self):super().__init__('data_generator_node')self.data=Int32()self.data.data=0self.writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='timed_synthetic_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')self.writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')self.writer.create_topic(topic_info)self.timer=self.create_timer(1,self.timer_callback)deftimer_callback(self):self.writer.write('synthetic',serialize_message(self.data),self.get_clock().now().nanoseconds)self.data.data+=1defmain(args=None):rclpy.init(args=args)dgn=DataGeneratorNode()rclpy.spin(dgn)rclpy.shutdown()if__name__=='__main__':main()


key: chroma:document
string_value:
Language: unknown

storage_options=rosbag2_py._storage.StorageOptions(uri='timed_synthetic_bag',storage_id='mcap')

Language: unknown

topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')self.writer.create_topic(topic_info)

Language: unknown

self.timer=self.create_timer(1,self.timer_callback)

Language: unknown

self.writer.write('synthetic',serialize_message(self.data),self.get_clock().now().nanoseconds)

Language: unknown entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main','data_generator_node = bag_recorder_nodes_py.data_generator_node:main',],},

Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

merge

install -

packages

select bag_recorder_nodes_py

Language: unknown

source install/setup.bash

Language: unknown

source install/setup.bash


key: chroma:document
string_value:
Language: unknown

source install/setup.bash

Language: unknown

call install/setup.bat

Language: unknown

ros2 run bag_recorder_nodes_py data_generator_node

Language: unknown

ros2 bag play timed_synthetic_bag

Language: unknown

ros2 topic echo /synthetic

Language: unknown


key: chroma:document
string_value:
ros2 topic echo /synthetic

Language: unknown

fromrclpy.clockimportClockfromrclpy.durationimportDurationfromrclpy.serializationimportserialize_messagefromexample_interfaces.msgimportInt32importrosbag2_pydefmain(args=None):writer=rosbag2_py.SequentialWriter()storage_options=rosbag2_py._storage.StorageOptions(uri='big_synthetic_bag',storage_id='mcap')converter_options=rosbag2_py._storage.ConverterOptions('','')writer.open(storage_options,converter_options)topic_info=rosbag2_py._storage.TopicMetadata(id=0,name='synthetic',type='example_interfaces/msg/Int32',serialization_format='cdr')writer.create_topic(topic_info)time_stamp=Clock().now()foriiinrange(0,100):data=Int32()data.data=iiwriter.write('synthetic',serialize_message(data),time_stamp.nanoseconds)time_stamp+=Duration(seconds=1)if__name__=='__main__':main()

Language: unknown

time_stamp=Clock().now()foriiinrange(0,100):data=Int32()data.data=iiwriter.write('synthetic',serialize_message(data),time_stamp.nanoseconds)time_stamp+=Duration(seconds=1)


key: chroma:document
string_value:
Language: unknown entry_points={'console_scripts':['simple_bag_recorder = bag_recorder_nodes_py.simple_bag_recorder:main','data_generator_node = bag_recorder_nodes_py.data_generator_node:main','data_generator_executable = bag_recorder_nodes_py.data_generator_executable:main',],},

Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

packages

select bag_recorder_nodes_py

Language: unknown

colcon build -

merge

install -

packages

select bag_recorder_nodes_py

Language: unknown

source install/setup.bash

Language: unknown

source install/setup.bash

Language: unknown

call install/setup.bat

Language: unknown

ros2 run bag_recorder_nodes_py data_generator_executable

Language: unknown

ros2 bag play big_synthetic_bag

Language: unknown

ros2 topic echo /synthetic


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

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

CLI

Tools/Understanding

ROS2

Topics/Understanding

ROS2

Topics.html

Section: Installation

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


key: chroma:document
string_value:
Understanding topicsGoal:Use rqt_graph and command line tools to introspect ROS 2 topics.Tutorial level:BeginnerTime:20 minutesContentsBackgroundPrerequisitesTasks1 Setup2 rqt_graph3 ros2 topic list4 ros2 topic echo5 ros2 topic info6 ros2 interface show7 ros2 topic pub8 ros2 topic hz9 ros2 topic bw10 ros2 topic find11 Clean upSummaryNext stepsBackgroundROS 2 breaks complex systems down into many modular nodes. Topics are a vital element of the ROS graph that act as a bus for nodes to exchange messages.A node may publish data to any number of topics and simultaneously have subscriptions to any number of topics.Topics are one of the main ways in which data is moved between nodes and therefore between different parts of the system.PrerequisitesTheprevious tutorialprovides some useful background information on nodes that is built upon here.As always, don’t forget to source ROS 2 inevery new terminal you open.Tasks1 SetupBy now you should be comfortable starting up turtlesim.Open a new terminal and run:ros2


key: chroma:document
string_value:
starting up turtlesim.Open a new terminal and run:ros2 run turtlesim turtlesim_nodeOpen another terminal and run:ros2 run turtlesim turtle_teleop_keyRecall from theprevious tutorialthat the names of these nodes are/turtlesimand/teleop_turtleby default.2 rqt_graphThroughout this tutorial, we will userqt_graphto visualize the changing nodes and topics, as well as the connections between them.Theturtlesim tutorialtells you how to install rqt and all its plugins, includingrqt_graph.To run rqt_graph, open a new terminal and enter the command:rqt_graphYou can also open rqt_graph by openingrqtand selectingPlugins>Introspection>Node Graph.You should see the above nodes and topic, as well as two actions around the periphery of the graph (let’s ignore those for now). If you hover your mouse over the topic in the center, you’ll see the color highlighting like in the image above.The graph is depicting how the/turtlesimnode and the/teleop_turtlenode are communicating with each other over a topic. The/teleop_turtlenode


key: chroma:document
string_value:
with each other over a topic. The/teleop_turtlenode is publishing data (the keystrokes you enter to move the turtle around) to the/turtle1/cmd_veltopic, and the/turtlesimnode is subscribed to that topic to receive the data.The highlighting feature of rqt_graph is very helpful when examining more complex systems with many nodes and topics connected in many different ways.rqt_graph is a graphical introspection tool. Now we’ll look at some command line tools for introspecting topics.3 ros2 topic listRunning theros2topiclistcommand in a new terminal will return a list of all the topics currently active in the system:/parameter_events/rosout/turtle1/cmd_vel/turtle1/color_sensor/turtle1/poseros2topiclist-twill return the same list of topics, this time with the topic type appended in brackets:/parameter_events [rcl_interfaces/msg/ParameterEvent]/rosout [rcl_interfaces/msg/Log]/turtle1/cmd_vel [geometry_msgs/msg/Twist]/turtle1/color_sensor [turtlesim/msg/Color]/turtle1/pose [turtlesim/msg/Pose]These attributes,


key: chroma:document
string_value:
[turtlesim/msg/Pose]These attributes, particularly the type, are how nodes know they’re talking about the same information as it moves over topics.If you’re wondering where all these topics are in rqt_graph, you can uncheck all the boxes underHide:For now, though, leave those options checked to avoid confusion.4 ros2 topic echoTo see the data being published on a topic, use:ros2 topic echo <topic_name>Since we know that/teleop_turtlepublishes data to/turtlesimover the/turtle1/cmd_veltopic, let’s useechoto introspect that topic:ros2 topic echo /turtle1/cmd_velAt first, this command won’t return any data. That’s because it’s waiting for/teleop_turtleto publish something.Return to the terminal whereturtle_teleop_keyis running and use the arrows to move the turtle around. Watch the terminal where yourechois running at the same time, and you’ll see position data being published for every movement you make:linear:x: 2.0y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---Now return to rqt_graph and uncheck


key: chroma:document
string_value:
0.0y: 0.0z: 0.0---Now return to rqt_graph and uncheck theDebugbox./_ros2cli_26646is the node created by theechocommand we just ran (the number might be different). Now you can see that the publisher is publishing data over thecmd_veltopic, and two subscribers are subscribed to it.5 ros2 topic infoTopics don’t have to only be one-to-one communication; they can be one-to-many, many-to-one, or many-to-many.Another way to look at this is running:ros2 topic info /turtle1/cmd_velWhich will return:Type: geometry_msgs/msg/TwistPublisher count: 1Subscription count: 26 ros2 interface showNodes send data over topics using messages. Publishers and subscribers must send and receive the same type of message to communicate.The topic types we saw earlier after runningros2topiclist-tlet us know what message type is used on each topic. Recall that thecmd_veltopic has the type:geometry_msgs/msg/TwistThis means that in the packagegeometry_msgsthere is amsgcalledTwist.Now we can runros2interfaceshow<msg_type>on this type to


key: chroma:document
string_value:
we can runros2interfaceshow<msg_type>on this type to learn its details. Specifically, what structure of data the message expects.ros2 interface show geometry_msgs/msg/TwistFor the message type from above it yields:#Thisexpressesvelocityinfreespacebrokenintoitslinearandangularparts.Vector3  linearfloat64 xfloat64 yfloat64 zVector3  angularfloat64 xfloat64 yfloat64 zThis tells you that the/turtlesimnode is expecting a message with two vectors,linearandangular, of three elements each. If you recall the data we saw/teleop_turtlepassing to/turtlesimwith theechocommand, it’s in the same structure:linear:x: 2.0y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---7 ros2 topic pubNow that you have the message structure, you can publish data to a topic directly from the command line using:ros2 topic pub <topic_name> <msg_type> '<args>'The'<args>'argument is the actual data you’ll pass to the topic, in the structure you just discovered in the previous section.The turtle (and commonly the real robots which it is meant to emulate)


key: chroma:document
string_value:
(and commonly the real robots which it is meant to emulate) require a steady stream of commands to operate continuously. So, to get the turtle moving, and keep it moving, you can use the following command. It’s important to note that this argument needs to be input in YAML syntax. Input the full command like so:ros2 topic pub /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: 1.8}}"With no command-line options,ros2topicpubpublishes the command in a steady stream at 1 Hz.At times you may want to publish data to your topic only once (rather than continuously). To publish your command just once add the--onceoption.ros2 topic pub --once -w 2 /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: 1.8}}"--onceis an optional argument meaning “publish one message then exit”.-w2is an optional argument meaning “wait for two matching subscriptions”. This is needed because we have both turtlesim and the topic echo


key: chroma:document
string_value:
is needed because we have both turtlesim and the topic echo subscribed.You will see the following output in the terminal:Waiting for at least 2 matching subscription(s)...publisher: beginning looppublishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))And you will see your turtle move like so:You can refresh rqt_graph to see what’s happening graphically. You will see that theros2topicpub...node (/_ros2cli_30358) is publishing over the/turtle1/cmd_veltopic, which is being received by both theros2topicecho...node (/_ros2cli_26646) and the/turtlesimnode now.Finally, you can runechoon theposetopic and recheck rqt_graph:ros2 topic echo /turtle1/poseYou can see that the/turtlesimnode is also publishing to theposetopic, which the newechonode has subscribed to.When publishing messages with timestamps,pubhas two methods to automatically fill them out with the current time. For messages with astd_msgs/msg/Header, the header


key: chroma:document
string_value:
time. For messages with astd_msgs/msg/Header, the header field can be set toautoto fill out thestampfield.ros2 topic pub /pose geometry_msgs/msg/PoseStamped '{header: "auto", pose: {position: {x: 1.0, y: 2.0, z: 3.0}}}'If the message does not use a full header, but just has a field with typebuiltin_interfaces/msg/Time, that can be set to the valuenow.ros2 topic pub /reference sensor_msgs/msg/TimeReference '{header: "auto", time_ref: "now", source: "dumy"}'8 ros2 topic hzYou can also view the rate at which data is published using:ros2 topic hz /turtle1/poseIt will return data on the rate at which the/turtlesimnode is publishing data to theposetopic.average rate: 59.354min: 0.005s max: 0.027s std dev: 0.00284s window: 58Recall that you set the rate ofturtle1/cmd_velto publish at a steady 1 Hz usingros2topicpub--rate1. If you run the above command withturtle1/cmd_velinstead ofturtle1/pose, you will see an average reflecting that rate.9 ros2 topic bwThe bandwidth used by a topic can be viewed using:ros2 topic


key: chroma:document
string_value:
bwThe bandwidth used by a topic can be viewed using:ros2 topic bw /turtle1/poseIt returns the bandwidth utilization and number of messages being published to the/turtle1/posetopic.Subscribed to [/turtle1/pose]1.51 KB/s from 62 messagesMessage size mean: 0.02 KB min: 0.02 KB max: 0.02 KB10 ros2 topic findTo list a list of available topics of a given type use:ros2 topic find <topic_type>Recall that thecmd_veltopic has the type:geometry_msgs/msg/TwistUsing thefindcommand outputs topics available when given the message type:ros2 topic find geometry_msgs/msg/TwistThis outputs:/turtle1/cmd_vel11 Clean upAt this point you’ll have a lot of nodes running. Don’t forget to stop them by enteringCtrl+Cin each terminal.SummaryNodes publish information over topics, which allows any number of other nodes to subscribe to and access that information. In this tutorial you examined the connections between several nodes over topics using rqt_graph and command line tools. You should now have a good idea of how data moves


key: chroma:document
string_value:
line tools. You should now have a good idea of how data moves around a ROS 2 system.Next stepsNext you’ll learn about another communication type in the ROS graph with the tutorialUnderstanding services.


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtle_teleop_key

Language: unknown

rqt_graph

Language: unknown

/parameter_events/rosout/turtle1/cmd_vel/turtle1/color_sensor/turtle1/pose

Language: unknown /parameter_events [rcl_interfaces/msg/ParameterEvent]/rosout [rcl_interfaces/msg/Log]/turtle1/cmd_vel [geometry_msgs/msg/Twist]/turtle1/color_sensor [turtlesim/msg/Color]/turtle1/pose [turtlesim/msg/Pose]

Language: unknown

ros2 topic echo <topic_name>

Language: unknown

ros2 topic echo /turtle1/cmd_vel

Language: unknown linear:x: 2.0y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---

Language: unknown

ros2 topic info /turtle1/cmd_vel

Language: unknown Type: geometry_msgs/msg/TwistPublisher count: 1Subscription count: 2

Language: unknown

geometry_msgs/msg/Twist

Language: unknown

ros2 interface show geometry_msgs/msg/Twist


key: chroma:document
string_value:
Language: unknown

ros2 interface show geometry_msgs/msg/Twist

Language: unknown #Thisexpressesvelocityinfreespacebrokenintoitslinearandangularparts.Vector3  linearfloat64 xfloat64 yfloat64 zVector3  angularfloat64 xfloat64 yfloat64 z

Language: unknown linear:x: 2.0y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---

Language: unknown ros2 topic pub <topic_name> <msg_type> '<args>'

Language: unknown ros2 topic pub /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: 1.8}}"

Language: unknown ros2 topic pub --once -w 2 /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: 1.8}}"

Language: unknown Waiting for at least 2 matching subscription(s)...publisher: beginning looppublishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

Language: unknown

ros2 topic echo /turtle1/pose


key: chroma:document
string_value:
Language: unknown

ros2 topic echo /turtle1/pose

Language: unknown ros2 topic pub /pose geometry_msgs/msg/PoseStamped '{header: "auto", pose: {position: {x: 1.0, y: 2.0, z: 3.0}}}'

Language: unknown ros2 topic pub /reference sensor_msgs/msg/TimeReference '{header: "auto", time_ref: "now", source: "dumy"}'

Language: unknown

ros2 topic hz /turtle1/pose

Language: unknown average rate: 59.354min: 0.005s max: 0.027s std dev: 0.00284s window: 58

Language: unknown

ros2 topic bw /turtle1/pose

Language: unknown Subscribed to [/turtle1/pose]1.51 KB/s from 62 messagesMessage size mean: 0.02 KB min: 0.02 KB max: 0.02 KB

Language: unknown

ros2 topic find <topic_type>

Language: unknown

geometry_msgs/msg/Twist

Language: unknown

ros2 topic find geometry_msgs/msg/Twist

Language: unknown

/turtle1/cmd_vel


key: chroma:document
string_value:
Title: The Ros2Supervisor Node

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

Supervisor.html

Section: Installation

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


key: chroma:document
string_value:
The Ros2Supervisor NodeGoal:Extend the interface with a default Supervisor robot, namedRos2Supervisor.Tutorial level:AdvancedTime:10 minutesContentsBackgroundPrerequisitesTheRos2SupervisorClock topicImport a Webots nodeRemove a Webots imported nodeRecord animationsSummaryBackgroundIn this tutorial, you will learn how to enable theRos2Supervisornode which enhances the interface by creating additional services and topics to interact with the simulation. You can, for example, record animations or spawn Webots nodes directly from the ROS 2 interface while the simulation is running. These instructions list in details the current implemented features and how to use them.PrerequisitesBefore proceeding with this tutorial, make sure you have completed the following:Understanding of ROS 2 nodes and topics covered in the beginnerTutorials.Knowledge of Webots and ROS 2 and its interface package.Familiarity withSetting up a robot simulation (Basic).TheRos2SupervisorTheRos2Supervisoris made of two main parts:A Webots


key: chroma:document
string_value:
made of two main parts:A Webots Robot node added to the simulation world. Itssupervisorfield is set to TRUE.A ROS 2 node that connects to the Webots Robot as an extern controller (in a similar way to your own robot plugin).The ROS 2 node acts as a controller that calls Supervisor API functions to control or interact with the simulation world. User interactions with the ROS 2 node are mainly performed through services and topics.These nodes can be automatically created at the Webots launch using theros2_supervisorparameter in theWebotsLauncher.webots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]),mode=mode,ros2_supervisor=True)Thewebots._supervisorobject must also be included in theLaunchDescriptionreturned by the launch file.returnLaunchDescription([webots,webots._supervisor,# This action will kill all nodes once the Webots simulation has


key: chroma:document
string_value:
This action will kill all nodes once the Webots simulation has exitedlaunch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))])More information about launch files forwebots_ros2projects can be found inSetting up a robot simulation (Basic).Clock topicTheRos2Supervisornode is responsible to get the time of the Webots simulation and publish it to the/clocktopic. This means that it is mandatory to spawn theRos2Supervisorif some other nodes have theiruse_sim_timeparameter set totrue. More information about the/clocktopic can be found in theROS wiki.Import a Webots nodeTheRos2Supervisornode also allows you to spawn Webots nodes from strings through a service.The service is named/Ros2Supervisor/spawn_node_from_stringand is of typewebots_ros2_msgs/srv/SpawnNodeFromString. TheSpawnNodeFromStringtype expects adatastring as input and returns asuccessboolean.From the given string, the Supervisor node


key: chroma:document
string_value:
asuccessboolean.From the given string, the Supervisor node is getting the name of the imported node and adding it to an intern list for potential later removal (seeRemove a Webots imported node).The node is imported using theimportMFNodeFromString(nodeString)API function.Here is an example to import a simple Robot namedimported_robot:ros2servicecall/Ros2Supervisor/spawn_node_from_stringwebots_ros2_msgs/srv/SpawnNodeFromString"data: Robot { name \"imported_robot\" }"NoteIf you try to import some PROTOs in the node string, their respective URLs must be declared in the .wbt world file as EXTERNPROTO or as IMPORTABLE EXTERNPROTO.Remove a Webots imported nodeOnce a node has been imported with the/Ros2Supervisor/spawn_node_from_stringservice, it can also be removed.This can be achieved by sending the name of the node to the topic named/Ros2Supervisor/remove_nodeof typestd_msgs/msg/String.If the node is indeed in the imported list, it is removed with theremove()API method.Here is an example on how to remove


key: chroma:document
string_value:
with theremove()API method.Here is an example on how to remove theimported_robotRobot:ros2topicpub--once/Ros2Supervisor/remove_nodestd_msgs/msg/String"{data: imported_robot}"Record animationsTheRos2Supervisornode also creates two additional services to record HTML5 animations.The/Ros2Supervisor/animation_start_recordingservice is of typewebots_ros2_msgs/srv/SetStringand allows to start the animation. TheSetStringtype expects avaluestring as input and returns asuccessboolean. The inputvaluerepresents the absolute path to the directory where the animations files should be saved.Here is an example on how to start an animation:ros2servicecall/Ros2Supervisor/animation_start_recordingwebots_ros2_msgs/srv/SetString"{value: "<ABSOLUTE_PATH>/index.html"}"The/Ros2Supervisor/animation_stop_recordingservice is of typewebots_ros2_msgs/srv/GetBooland allows to stop the animation.ros2servicecall/Ros2Supervisor/animation_stop_recordingwebots_ros2_msgs/srv/GetBool"{ask: True}"SummaryIn this tutorial, you learned how to


key: chroma:document
string_value:
True}"SummaryIn this tutorial, you learned how to enable theRos2Supervisorand how to extend the interface with the Webots simulation. The node creates multiple services and topics to interact with and modify the simulation.


key: chroma:document
string_value:
Code Examples:

Language: unknown

webots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]),mode=mode,ros2_supervisor=True)

Language: unknown returnLaunchDescription([webots,webots._supervisor,# This action will kill all nodes once the Webots simulation has exitedlaunch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))])

Language: unknown ros2servicecall/Ros2Supervisor/spawn_node_from_stringwebots_ros2_msgs/srv/SpawnNodeFromString"data: Robot { name \"imported_robot\" }"

Language: unknown

ros2topicpub-

once/Ros2Supervisor/remove_nodestd_msgs/msg/String"{data: imported_robot}"

Language: unknown

ros2servicecall/Ros2Supervisor/animation_start_recordingwebots_ros2_msgs/srv/SetString"{value: "<ABSOLUTE_PATH>/index.html"}"

Language: unknown

ros2servicecall/Ros2Supervisor/animation_stop_recordingwebots_ros2_msgs/srv/GetBool"{ask: True}"


key: chroma:document
string_value:
Title: Glossary

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

Section: Installation

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


key: chroma:document
string_value:
GlossaryGlossary of terms used throughout this documentation:APIAn API, or Application Programming Interface, is an interface that is provided by an “application”, which in this case is usually a shared library or other language appropriate shared resource. APIs are made up of files that define a contract between the software using the interface and the software providing the interface. These files typically manifest as header files in C and C++ and as Python files in Python. In either case it is important that APIs are grouped and described in documentation and that they are declared as either public or private. Public interfaces are subject to change rules and changes to the public interfaces prompt a new version number of the software that provides them.client_libraryA client library is anAPIthat provides access to the ROS graph using primitive middleware concepts like Topics, Services, and Actions.packageA single unit of software, including source code, build system files, documentation, tests, and


key: chroma:document
string_value:
source code, build system files, documentation, tests, and other associated resources.REPROS Enhancement Proposal. A document that describes an enhancement, standardization, or convention for the ROS community. The associated REP approval process allows the community to iterate on a proposal until some consensus has been made, at which point it can be ratified and implemented, which then becomes documentation. All REPs are viewable from theREP index.VCSVersion Control System, such as CVS, SVN, git, mercurial, etc…rclcppThe C++ specificClient Libraryfor ROS. This includes any middleware related APIs as well as the related message generation of C++ data structures based on interface definitions like Messages, Services, and Actions.repositoryA collection of packages usually managed using aVCSlike git or mercurial and usually hosted on a site like GitHub or BitBucket. In the context of this document, repositories usually contain one or morepackagesof one type or another.


key: chroma:document
string_value:
Title: Working with multiple ROS 2 middleware implementations URL: https://docs.ros.org/en/jazzy/How-To-Guides/Working-with-multiple-RMW-implementations.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Working with multiple ROS 2 middleware implementationsTable of ContentsPrerequisitesSpecifying RMW implementationsAdding RMW implementations to your workspaceTroubleshootingChecking the Current RMWEnsuring use of a particular RMW implementationRTI Connext on OSX: Failure due to insufficient shared memory kernel settingsThis page explains the default RMW implementation and how to specify an alternative.PrerequisitesYou should have already read theDDS and ROS middleware implementations page.Specifying RMW implementationsTo have multiple RMW implementations available for use you must have installed the ROS 2 binaries and any additional dependencies for specific RMW implementations, or built ROS 2 from source with multiple RMW implementations in the workspace (the RMW implementations are included in the build by default if their compile-time dependencies are met). SeeInstall DDS implementations.Both C++ and Python nodes support an environment variableRMW_IMPLEMENTATIONthat allows the user to select the RMW


key: chroma:document
string_value:
allows the user to select the RMW implementation to use when running ROS 2 applications.The user may set this variable to a specific implementation identifier, such asrmw_cyclonedds_cpp,rmw_fastrtps_cpp,rmw_connextdds, orrmw_gurumdds_cpp.For example, to run the talker demo using the C++ talker and Python listener with the Connext RMW implementation:LinuxmacOSWindowsRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalker# Run in another terminalRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_pylistenerRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalker# Run in another terminalRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_pylistenersetRMW_IMPLEMENTATION=rmw_connextdds ros2 run demo_nodes_cpp talkerREM run in another terminalsetRMW_IMPLEMENTATION=rmw_connextdds ros2 run demo_nodes_py listenerAdding RMW implementations to your workspaceSuppose that you have built your ROS 2 workspace with only Fast DDS installed and therefore only the Fast DDS RMW implementation built. The last time your


key: chroma:document
string_value:
only the Fast DDS RMW implementation built. The last time your workspace was built, any other RMW implementation packages,rmw_connextddsfor example, were probably unable to find installations of the relevant DDS implementations. If you then install an additional DDS implementation, Connext for example, you will need to re-trigger the check for a Connext installation that occurs when the Connext RMW implementation is being built. You can do this by specifying the--cmake-clean-cacheflag on your next workspace build, and you should see that the RMW implementation package then gets built for the newly installed DDS implementation.It is possible to run into a problem when “rebuilding” the workspace with an additional RMW implementation using the--cmake-clean-cacheoption where the build complains about the default RMW implementation changing. To resolve this, you can either set the default implementation to what is was before with theRMW_IMPLEMENTATIONCMake argument or you can delete the build folder for packages


key: chroma:document
string_value:
argument or you can delete the build folder for packages that complain and continue the build with--packages-start<packagename>.TroubleshootingChecking the Current RMWTo check the RMW that is currently in use you simply check theRMW_IMPLEMENTATIONenvironment variable. On Linux systemsprintenvprints the full list of environment variables. Other operating systems will have other procedures for viewing environment variables. IfRMW_IMPLEMENTATIONis not in the environment it is safe to assume you are using the default for your ROS distro, otherwise the current RMW is the value listed. The default RMW for each ROS Distro can be found inREP-2000.Ensuring use of a particular RMW implementationIf theRMW_IMPLEMENTATIONenvironment variable is set to an RMW implementation for which support is not installed, you will see an error message similar to the following if you have only one implementation installed:ExpectedRMWimplementationidentifierof'rmw_connextdds'butinsteadfound'rmw_fastrtps_cpp',exitingwith102.If you


key: chroma:document
string_value:
you have support for multiple RMW implementations installed and you request use of one that is not installed, you will see something similar to:ErrorgettingRMWimplementationidentifier/RMWimplementationnotinstalled(expectedidentifierof'rmw_connextdds'),exitingwith1.If this occurs, double check that your ROS 2 installation includes support for the RMW implementation that you have specified in theRMW_IMPLEMENTATIONenvironment variable.If you want to switch between RMW implementations, verify that the ROS 2 daemon process is not running with the previous RMW implementation to avoid any issues between nodes and command line tools such asros2node. For example, if you run:RMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalkerandros2nodelistit will generate a daemon with a Fast DDS implementation:2131822.00.653589655044pts/8Sl16:140:00/usr/bin/python3/opt/ros/jazzy/bin/_ros2_daemon--rmw-implementationrmw_fastrtps_cpp--ros-domain-id0Even if you run the command line tool again with the correct RMW


key: chroma:document
string_value:
if you run the command line tool again with the correct RMW implementation, the daemon’s RMW implementation will not change and the ROS 2 command line tools will fail.To solve this, simply stop the daemon process:ros2daemonstopand rerun the ROS 2 command line tool with the correct RMW implementation.RTI Connext on OSX: Failure due to insufficient shared memory kernel settingsIf you receive an error message similar to below when running RTI Connext on OSX:[D0062|ENABLE]DDS_DomainParticipantPresentation_reserve_participant_index_entryports:!enable reserve participant index[D0062|ENABLE]DDS_DomainParticipant_reserve_participant_index_entryports:Unusable shared memory transport. For a more in-   depth explanation of the possible problem and solution, please visit https://community.rti.com/kb/osx510.This error is caused by an insufficient number or size of shared memory segments allowed by the operating system. As a result, theDomainParticipantis unable to allocate enough resources and calculate its participant


key: chroma:document
string_value:
to allocate enough resources and calculate its participant index which causes the error.You can increase the shared memory resources of your machine either temporarily or permanently.To increase the settings temporarily, you can run the following commands as user root:/usr/sbin/sysctl -w kern.sysv.shmmax=419430400/usr/sbin/sysctl -w kern.sysv.shmmin=1/usr/sbin/sysctl -w kern.sysv.shmmni=128/usr/sbin/sysctl -w kern.sysv.shmseg=1024/usr/sbin/sysctl -w kern.sysv.shmall=262144To increase the settings permanently, you will need to edit or create the file/etc/sysctl.conf. Creating or editing this file will require root permissions. Either add to your existingetc/sysctl.conffile or create/etc/sysctl.confwith the following lines:kern.sysv.shmmax=419430400kern.sysv.shmmin=1kern.sysv.shmmni=128kern.sysv.shmseg=1024kern.sysv.shmall=262144You will need to reboot the machine after modifying this file to have the changes take effect.This solution is edited from the RTI Connext community forum. See theoriginal postfor more


key: chroma:document
string_value:
Code Examples:

Language: unknown RMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalker# Run in another terminalRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_pylistener

Language: unknown RMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalker# Run in another terminalRMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_pylistener

Language: unknown setRMW_IMPLEMENTATION=rmw_connextdds ros2 run demo_nodes_cpp talkerREM run in another terminalsetRMW_IMPLEMENTATION=rmw_connextdds ros2 run demo_nodes_py listener

Language: unknown

ExpectedRMWimplementationidentifierof'rmw_connextdds'butinsteadfound'rmw_fastrtps_cpp',exitingwith102.

Language: unknown

ErrorgettingRMWimplementationidentifier/RMWimplementationnotinstalled(expectedidentifierof'rmw_connextdds'),exitingwith1.

Language: unknown

RMW_IMPLEMENTATION=rmw_connextddsros2rundemo_nodes_cpptalker

Language: unknown

ros2nodelist

Language: unknown

2131822.00.653589655044pts/8Sl16:140:00/usr/bin/python3/opt/ros/jazzy/bin/_ros2_daemon-

rmw


key: chroma:document
string_value:
rmw

implementationrmw_fastrtps_cpp-

ros

domain

id0

Language: unknown

ros2daemonstop

Language: unknown [D0062|ENABLE]DDS_DomainParticipantPresentation_reserve_participant_index_entryports:!enable reserve participant index[D0062|ENABLE]DDS_DomainParticipant_reserve_participant_index_entryports:Unusable shared memory transport. For a more in-   depth explanation of the possible problem and solution, please visit https://community.rti.com/kb/osx510.

Language: unknown

/usr/sbin/sysctl

w kern.sysv.shmmax=419430400/usr/sbin/sysctl

w kern.sysv.shmmin=1/usr/sbin/sysctl

w kern.sysv.shmmni=128/usr/sbin/sysctl

w kern.sysv.shmseg=1024/usr/sbin/sysctl

w kern.sysv.shmall=262144

Language: unknown

kern.sysv.shmmax=419430400kern.sysv.shmmin=1kern.sysv.shmmni=128kern.sysv.shmseg=1024kern.sysv.shmall=262144


key: chroma:document
string_value:
Title: Creating an action

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

an

Action.html

Section: Installation

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


key: chroma:document
string_value:
Creating an actionGoal:Define an action in a ROS 2 package.Tutorial level:IntermediateTime:5 minutesContentsBackgroundPrerequisitesTasks1 Creating an interface package2 Defining an action3 Building an actionSummaryNext stepsRelated contentBackgroundYou learned about actions previously in theUnderstanding actionstutorial. Like the other communication types and their respective interfaces (topics/msg and services/srv), you can also custom-define actions in your packages. This tutorial shows you how to define and build an action that you can use with the action server and action client you will write in the next tutorial.PrerequisitesYou should haveROS 2andcolconinstalled.You should know how to set up aworkspaceand create packages.Remember tosource your ROS 2 installationfirst.Tasks1 Creating an interface packageLinuxmacOSWindowsmkdir-p~/ros2_ws/src# you can reuse an existing workspace with this naming conventioncd~/ros2_ws/src


key: chroma:document
string_value:
existing workspace with this naming conventioncd~/ros2_ws/src ros2pkgcreate--licenseApache-2.0custom_action_interfacesmkdir-p~/ros2_ws/srccd~/ros2_ws/src ros2pkgcreate--licenseApache-2.0custom_action_interfacesmd\ros2_ws\srccd\ros2_ws\src ros2pkgcreate--licenseApache-2.0custom_action_interfaces2 Defining an actionActions are defined in.actionfiles of the form:# Request---# Result---# FeedbackAn action definition is made up of three message definitions separated by---.Arequestmessage is sent from an action client to an action server initiating a new goal.Aresultmessage is sent from an action server to an action client when a goal is done.Feedbackmessages are periodically sent from an action server to an action client with updates about a goal.An instance of an action is typically referred to as agoal.Say we want to define a new action “Fibonacci” for computing theFibonacci sequence.Create anactiondirectory in our ROS 2 packagecustom_action_interfaces:LinuxmacOSWindowscdcustom_action_interfaces


key: chroma:document
string_value:
mkdiractioncdcustom_action_interfaces mkdiractioncdcustom_action_interfaces mdactionWithin theactiondirectory, create a file calledFibonacci.actionwith the following contents:int32 order---int32[] sequence---int32[] partial_sequenceThe goal request is theorderof the Fibonacci sequence we want to compute, the result is the finalsequence, and the feedback is thepartial_sequencecomputed so far.3 Building an actionBefore we can use the new Fibonacci action type in our code, we must pass the definition to the rosidl code generation pipeline.This is accomplished by adding the following lines to ourCMakeLists.txtbefore theament_package()line:find_package(rosidl_default_generatorsREQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"action/Fibonacci.action")We should also add the required dependencies to ourpackage.xml:<buildtool_depend>rosidl_default_generators</buildtool_depend><member_of_group>rosidl_interface_packages</member_of_group>We should now be able to build the package containing theFibonacciaction


key: chroma:document
string_value:
now be able to build the package containing theFibonacciaction definition:# Change to the root of the workspacecd~/ros2_ws# BuildcolconbuildWe’re done!By convention, action types will be prefixed by their package name and the wordaction. So when we want to refer to our new action, it will have the full namecustom_action_interfaces/action/Fibonacci.We can check that our action built successfully with the command line tool. First source our workspace:LinuxmacOSWindowssourceinstall/local_setup.bashsourceinstall/local_setup.bashcallinstall\local_setup.batNow check that our action definition exists:ros2interfaceshowcustom_action_interfaces/action/FibonacciYou should see the Fibonacci action definition printed to the screen.SummaryIn this tutorial, you learned the structure of an action definition. You also learned how to correctly build a new action interface usingCMakeLists.txtandpackage.xml, and how to verify a successful build.Next stepsNext, let’s utilize your newly defined action interface by creating an


key: chroma:document
string_value:
utilize your newly defined action interface by creating an action service and client (inPythonorC++).Related contentFor more detailed information about ROS actions, please refer to thedesign article.


key: chroma:document
string_value:
Code Examples:

Language: unknown mkdir-p~/ros2_ws/src# you can reuse an existing workspace with this naming conventioncd~/ros2_ws/src ros2pkgcreate--licenseApache-2.0custom_action_interfaces

Language: unknown

mkdir

p~/ros2_ws/srccd~/ros2_ws/src

ros2pkgcreate-

licenseApache

2.0custom_action_interfaces

Language: unknown

md\ros2_ws\srccd\ros2_ws\src

ros2pkgcreate-

licenseApache

2.0custom_action_interfaces

Language: unknown

# Request--

# Result--

# Feedback

Language: unknown

cdcustom_action_interfaces

mkdiraction

Language: unknown

cdcustom_action_interfaces

mkdiraction

Language: unknown

cdcustom_action_interfaces

mdaction

Language: unknown

int32 order--

int32[] sequence--

int32[] partial_sequence

Language: unknown

find_package(rosidl_default_generatorsREQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"action/Fibonacci.action")

Language: unknown

<buildtool_depend>rosidl_default_generators</buildtool_depend><member_of_group>rosidl_interface_packages</member_of_group>


key: chroma:document
string_value:
Language: unknown # Change to the root of the workspacecd~/ros2_ws# Buildcolconbuild

Language: unknown

sourceinstall/local_setup.bash

Language: unknown

sourceinstall/local_setup.bash

Language: unknown

callinstall\local_setup.bat

Language: unknown

ros2interfaceshowcustom_action_interfaces/action/Fibonacci


key: chroma:document
string_value:
Title: Subsequent Releases

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

To

Guides/Releasing/Subsequent

Releases.html

Section: Installation

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


key: chroma:document
string_value:
Subsequent ReleasesThis guide explains how to release new versions of ROS packages that have already been released before.Table of ContentsBe part of the release teamInstall dependenciesSet up a Personal Access TokenEnsure repositories are up-to-dateUpdating ChangelogBump the package versionBloom ReleaseNext StepsBe part of the release teamIf you are not part of the release team that has write access to the release repository, followJoin a release team.Install dependenciesInstall tools that you will use in the upcoming steps according to your platform:deb (eg. Ubuntu)RPM (eg. RHEL)Othersudoaptinstallpython3-bloompython3-catkin-pkgsudodnfinstallpython3-bloompython3-catkin_pkgpip3install-Ubloomcatkin_pkgMake sure you have rosdep initialized:sudorosdepinit rosdepupdateNote that therosdepinitcommand may fail if it has already been initialized in the past; this can safely be ignored.Set up a Personal Access TokenWarningIf the file~/.config/bloomexists on your computer, it is likely that you have done this


key: chroma:document
string_value:
on your computer, it is likely that you have done this before so you should skip this section.During the release process, multiple HTTPS Git operations will be performed that require password authentication. To avoid being repeatedly asked for a password, aPersonal Access Token (PAT)will be set up. If you have multi-factor authentication setup on your GitHub account, youmustsetup a Personal Access Token.Create a Personal Access Token by:Log in to GitHub and go toPersonal access tokens.Click theGenerate new tokenbutton.In the dropdown, selectGenerate new token (classic)SetNoteto something likeBloomtoken.SetExpirationtoNo expiration.Tick thepublic_repoandworkflowcheckboxes.Click theGenerate tokenbutton.After you have created the token, you will end up back at thePersonal access tokenspage.Copy the alphanumeric tokenthat is highlighted in green.Save your GitHub username and PAT to a new file called~/.config/bloom, with the format below:{ "github_user": "<your-github-username>", "oauth_token":


key: chroma:document
string_value:
below:{ "github_user": "<your-github-username>", "oauth_token": "<token-you-created-for-bloom>" }Ensure repositories are up-to-dateMake sure that:Your repository is hosted on a remote such as GitHub.You have a clone of the repository on your computer and are on the right branch.Both the remote repository and your clone are up-to-date.Updating ChangelogFor your users and for the developers, keep the changelog concise and up to date.catkin_generate_changelogOpen allCHANGELOG.rstfiles in an editor. You will see thatcatkin_generate_changeloghas auto-generated a forthcoming section with notes from commit messages:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Changelog for package your_package^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Forthcoming-----------*you can modify this commit message*and thisClean up the list of commit messages to concisely convey the notable changes that have been made to the packages since the last release, andcommit all the CHANGELOG.rst files.Do not modify theForthcomingheader.Bump the package


key: chroma:document
string_value:
files.Do not modify theForthcomingheader.Bump the package versionEvery release of the package must have a unique version number higher than the previous release. Run:catkin_prepare_releasewhich performs the following:increases the package version inpackage.xmlreplaces the headingForthcomingwithversion(date)(eg.0.0.1(2022-01-08)) inCHANGELOG.rstcommits those changescreates a tag (eg.0.0.1)pushes the changes and the tag to your remote repositoryNoteBy default the patch version of the package is incremented, such as from0.0.0to0.0.1. To increment the minor or major version instead, runcatkin_prepare_release--bumpminororcatkin_prepare_release--bumpmajor. For more details, seecatkin_prepare_release--help.Bloom ReleaseRun the following command, replacingmy_repowith the name of your repository with the packages:bloom-release--rosdistrojazzymy_repoBloom will automatically create a pull request for you againstrosdistro.Next StepsOnce your pull request has been submitted, usually within one or two days, one of the


key: chroma:document
string_value:
has been submitted, usually within one or two days, one of the maintainers of rosdistro will review and merge your Pull Request. If your package build is successful, in 24-48 hours your packages will become available in theros-testingrepository, where you cantest your pre-release binaries.Approximately every two to four weeks, the distribution’s release manager manually synchronizes the contents of ros-testing into the main ROS repository. This is when your packages actually become available to the rest of the ROS community. To get updates on when the next synchronization (sync) is coming, subscribe to thePackaging and Release Management Category on ROS Discourse.


key: chroma:document
string_value:
Code Examples:

Language: unknown

sudoaptinstallpython3

bloompython3

catkin

pkg

Language: unknown

sudodnfinstallpython3

bloompython3

catkin_pkg

Language: unknown

pip3install

Ubloomcatkin_pkg

Language: unknown

sudorosdepinit

rosdepupdate

Language: unknown

{

"github_user": "<your

github

username>",

"oauth_token": "<token

you

created

for

bloom>"

}

Language: unknown

catkin_generate_changelog

Language: unknown ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Changelog for package your_package^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Forthcoming-----------*you can modify this commit message*and this

Language: unknown

catkin_prepare_release

Language: unknown

bloom

release-

rosdistrojazzymy_repo


key: chroma:document
string_value:
Title: Creating a workspace

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

Client

Libraries/Creating

A

Workspace/Creating

A

Workspace.html

Section: Installation

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


key: chroma:document
string_value:
Creating a workspaceGoal:Create a workspace and learn how to set up an overlay for development and testing.Tutorial level:BeginnerTime:20 minutesContentsBackgroundPrerequisitesTasks1 Source ROS 2 environment2 Create a new directory3 Clone a sample repo4 Resolve dependencies5 Build the workspace with colcon6 Source the overlay7 Modify the overlaySummaryNext stepsBackgroundA workspace is a directory containing ROS 2 packages. Before using ROS 2, it’s necessary to source your ROS 2 installation workspace in the terminal you plan to work in. This makes ROS 2’s packages available for you to use in that terminal.You also have the option of sourcing an “overlay” - a secondary workspace where you can add new packages without interfering with the existing ROS 2 workspace that you’re extending, or “underlay”. Your underlay must contain the dependencies of all the packages in your overlay. Packages in your overlay will override packages in the underlay. It’s also possible to have several layers of underlays and


key: chroma:document
string_value:
It’s also possible to have several layers of underlays and overlays, with each successive overlay using the packages of its parent underlays.PrerequisitesROS 2 installationcolcon installationgit installationturtlesim installationHaverosdep installedUnderstanding of basic terminal commands (here’s a guide for Linux)Text editor of your choiceTasks1 Source ROS 2 environmentYour main ROS 2 installation will be your underlay for this tutorial. (Keep in mind that an underlay does not necessarily have to be the main ROS 2 installation.)Depending on how you installed ROS 2 (from source or binaries), and which platform you’re on, your exact source command will vary:LinuxmacOSWindowssource /opt/ros/jazzy/setup.bash. ~/ros2_install/ros2-osx/setup.bashRemember to use ax64NativeToolsCommandPromptforVS2019for executing the following commands, as we are going to build a workspace.call C:\dev\ros2\local_setup.batConsult theinstallation guideyou followed if these commands don’t work for you.2 Create a new directoryBest


key: chroma:document
string_value:
these commands don’t work for you.2 Create a new directoryBest practice is to create a new directory for every new workspace. The name doesn’t matter, but it is helpful to have it indicate the purpose of the workspace. Let’s choose the directory nameros2_ws, for “development workspace”:LinuxmacOSWindowsmkdir -p ~/ros2_ws/srccd ~/ros2_ws/srcmkdir -p ~/ros2_ws/srccd ~/ros2_ws/srcmd \ros2_ws\srccd \ros2_ws\srcAnother best practice is to put any packages in your workspace into thesrcdirectory. The above code creates asrcdirectory insideros2_wsand then navigates into it.3 Clone a sample repoEnsure you’re still in theros2_ws/srcdirectory before you clone.In the rest of the beginner developer tutorials, you will create your own packages, but for now you will practice putting a workspace together using existing packages.If you went through theBeginner: CLI Toolstutorials, you’ll be familiar withturtlesim, one of the packages inros_tutorials.A repo can have multiple branches. You need to check out the one that


key: chroma:document
string_value:
can have multiple branches. You need to check out the one that targets your installed ROS 2 distro. When you clone this repo, add the-bargument followed by that branch.In theros2_ws/srcdirectory, run the following command:git clone https://github.com/ros/ros_tutorials.git -b jazzyNowros_tutorialsis cloned in your workspace.  Theros_tutorialsrepository contains theturtlesimpackage, which we’ll use in the rest of this tutorial.  The other packages in this repository are not built because they contain aCOLCON_IGNOREfile.So far you have populated your workspace with a sample package, but it isn’t a fully-functional workspace yet. You need to resolve the dependencies first and then build the workspace.4 Resolve dependenciesBefore building the workspace, you need to resolve the package dependencies. You may have all the dependencies already, but best practice is to check for dependencies every time you clone. You wouldn’t want a build to fail after a long wait only to realize that you have missing


key: chroma:document
string_value:
to fail after a long wait only to realize that you have missing dependencies.From the root of your workspace (ros2_ws), run the following command:LinuxmacOSWindows# cd if you're still in the ``src`` directory with the ``ros_tutorials`` clonecd.. rosdepinstall-i--from-pathsrc--rosdistrojazzy-yrosdep only runs on Linux, so you can skip ahead to section “5 Build the workspace with colcon”.rosdep only runs on Linux, so you can skip ahead to section “5 Build the workspace with colcon”.If you installed ROS 2 on Linux from source or the binary archive, you will need to use the rosdep command from their installation instructions. Here are thefrom-source rosdep sectionand thebinary archive rosdep section.If you already have all your dependencies, the console will return:#AllrequiredrosdepsinstalledsuccessfullyPackages declare their dependencies in the package.xml file (you will learn more about packages in the next tutorial). This command walks through those declarations and installs the ones that are missing. You


key: chroma:document
string_value:
those declarations and installs the ones that are missing. You can learn more aboutrosdepin another tutorial (coming soon).5 Build the workspace with colconFrom the root of your workspace (ros2_ws), you can now build your packages using the command:LinuxmacOSWindowscolcon buildcolcon buildcolcon build --merge-installWindows doesn’t allow long paths, somerge-installwill combine all the paths into theinstalldirectory.The console will return the following message:Starting >>> turtlesimFinished <<< turtlesim [5.49s]Summary: 1 package finished [5.58s]NoteOther useful arguments forcolconbuild:--packages-up-tobuilds the package you want, plus all its dependencies, but not the whole workspace (saves time)--symlink-installsaves you from having to rebuild every time you tweak python scripts--event-handlersconsole_direct+shows console output while building (can otherwise be found in thelogdirectory)--executorsequentialprocesses the packages one by one instead of using parallelismOnce the build is finished, enter the


key: chroma:document
string_value:
of using parallelismOnce the build is finished, enter the command in the workspace root (~/ros2_ws):LinuxmacOSWindowslslsdirAnd you will see that colcon has created new directories:build  install  log  srcTheinstalldirectory is where your workspace’s setup files are, which you can use to source your overlay.6 Source the overlayBefore sourcing the overlay, it is very important that you open a new terminal, separate from the one where you built the workspace. Sourcing an overlay in the same terminal where you built, or likewise building where an overlay is sourced, may create complex issues.In the new terminal, source your main ROS 2 environment as the “underlay”, so you can build the overlay “on top of” it:LinuxmacOSWindowssource /opt/ros/jazzy/setup.bash. ~/ros2_install/ros2-osx/setup.bashIn this case you can use a normal command prompt, as we are not going to build any workspace in this terminal.call C:\dev\ros2\local_setup.batGo into the root of your workspace:LinuxmacOSWindowscd ~/ros2_wscd ~/ros2_wscd


key: chroma:document
string_value:
of your workspace:LinuxmacOSWindowscd ~/ros2_wscd ~/ros2_wscd \ros2_wsIn the root, source your overlay:LinuxmacOSWindowssource install/local_setup.bash. install/local_setup.bashcall install\setup.batNoteSourcing thelocal_setupof the overlay will only add the packages available in the overlay to your environment.setupsources the overlay as well as the underlay it was created in, allowing you to utilize both workspaces.So, sourcing your main ROS 2 installation’ssetupand then theros2_wsoverlay’slocal_setup, like you just did, is the same as just sourcingros2_ws’ssetup, because that includes the environment of its underlay.Now you can run theturtlesimpackage from the overlay:ros2 run turtlesim turtlesim_nodeBut how can you tell that this is the overlay turtlesim running, and not your main installation’s turtlesim?Let’s modify turtlesim in the overlay so you can see the effects:You can modify and rebuild packages in the overlay separately from the underlay.The overlay takes precedence over the underlay.7 Modify


key: chroma:document
string_value:
overlay takes precedence over the underlay.7 Modify the overlayYou can modifyturtlesimin your overlay by editing the title bar on the turtlesim window. To do this, locate theturtle_frame.cppfile in~/ros2_ws/src/ros_tutorials/turtlesim/src. Openturtle_frame.cppwith your preferred text editor.Find the functionsetWindowTitle("TurtleSim");, change the value"TurtleSim"to"MyTurtleSim", and save the file.Return to the first terminal where you rancolconbuildearlier and run it again.Return to the second terminal (where the overlay is sourced) and run turtlesim again:ros2 run turtlesim turtlesim_nodeYou will see the title bar on the turtlesim window now says “MyTurtleSim”.Even though your main ROS 2 environment was sourced in this terminal earlier, the overlay of yourros2_wsenvironment takes precedence over the contents of the underlay.To see that your underlay is still intact, open a brand new terminal and source only your ROS 2 installation. Run turtlesim again:ros2 run turtlesim turtlesim_nodeYou can see that


key: chroma:document
string_value:
again:ros2 run turtlesim turtlesim_nodeYou can see that modifications in the overlay did not actually affect anything in the underlay.SummaryIn this tutorial, you sourced your main ROS 2 distro install as your underlay, and created an overlay by cloning and building packages in a new workspace. The overlay gets prepended to the path, and takes precedence over the underlay, as you saw with your modified turtlesim.Using overlays is recommended for working on a small number of packages, so you don’t have to put everything in the same workspace and rebuild a huge workspace on every iteration.Next stepsNow that you understand the details behind creating, building and sourcing your own workspace, you can learn how tocreate your own packages.


key: chroma:document
string_value:
Code Examples:

Language: unknown

source /opt/ros/jazzy/setup.bash

Language: unknown

. ~/ros2_install/ros2

osx/setup.bash

Language: unknown

call C:\dev\ros2\local_setup.bat

Language: unknown

mkdir

p ~/ros2_ws/srccd ~/ros2_ws/src

Language: unknown

mkdir

p ~/ros2_ws/srccd ~/ros2_ws/src

Language: unknown

md \ros2_ws\srccd \ros2_ws\src

Language: unknown

git clone https://github.com/ros/ros_tutorials.git

b jazzy

Language: unknown # cd if you're still in the ``src`` directory with the ``ros_tutorials`` clonecd.. rosdepinstall-i--from-pathsrc--rosdistrojazzy-y

Language: unknown

#Allrequiredrosdepsinstalledsuccessfully

Language: unknown

colcon build

Language: unknown

colcon build

Language: unknown

colcon build -

merge

install

Language: unknown Starting >>> turtlesimFinished <<< turtlesim [5.49s]Summary: 1 package finished [5.58s]

Language: unknown

ls

Language: unknown

ls

Language: unknown

dir

Language: unknown build  install  log  src

Language: unknown


key: chroma:document
string_value:
Language: unknown build  install  log  src

Language: unknown

source /opt/ros/jazzy/setup.bash

Language: unknown

. ~/ros2_install/ros2

osx/setup.bash

Language: unknown

call C:\dev\ros2\local_setup.bat

Language: unknown

cd ~/ros2_ws

Language: unknown

cd ~/ros2_ws

Language: unknown

cd \ros2_ws

Language: unknown

source install/local_setup.bash

Language: unknown

. install/local_setup.bash

Language: unknown

call install\setup.bat

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtlesim_node

Language: unknown

ros2 run turtlesim turtlesim_node


key: source
string_value:
/Users/ad12/ros2-rag/exported_docs/ros2/How_to_use_ros2_tracing_to_trace_and_analyze_an_application.txt


key: chroma:document
string_value:
Title: How to use ros2_tracing to trace and analyze an application URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/ROS2-Tracing-Trace-and-Analyze.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
How to use ros2_tracing to trace and analyze an applicationThis tutorial shows how to useros2_tracingto trace and analyze a ROS 2 application. For this tutorial, the application will beperformance_test.OverviewThis tutorial covers:running and tracing aperformance_testrunanalyzing the trace data usingtracetools_analysisto plot the callback durationsPrerequisitesThis tutorial is aimed at real-time Linux systems. See thereal-time system setup tutorial. However, the tutorial will work if you are using a non-real-time Linux system.Installing and buildingInstall ROS 2 on Linux by following theinstallation instructions.NoteThis tutorial should generally work with all supported Linux distributions. However, you might need to adapt some commands.Installbabeltraceandros2trace.sudoapt-getupdate sudoapt-getinstall-ybabeltraceros-jazzy-ros2traceros-jazzy-tracetools-analysisSource the ROS 2 installation and verify that tracing is enabled:source/opt/ros/jazzy/setup.bash ros2runtracetoolsstatusYou should


key: chroma:document
string_value:
ros2runtracetoolsstatusYou should seeTracingenabledin the output.Then create a workspace, and cloneperformance_testandtracetools_analysis.cd~/ mkdir-ptracing_ws/srccdtracing_ws/src/ gitclonehttps://gitlab.com/ApexAI/performance_test.git gitclonehttps://github.com/ros-tracing/tracetools_analysis.git-bjazzycd..Install dependencies with rosdep.rosdepupdate rosdepinstall--from-pathssrc--ignore-src-yThen build and configureperformance_testfor ROS 2. See itsdocumentation.colconbuild--packages-selectperformance_test--cmake-args-DPERFORMANCE_TEST_RCLCPP_ENABLED=ONNext, we will run aperformance_testexperiment and trace it.TracingStep 1: TraceIn one terminal, source the workspace and set up tracing. When running the command, a list of ROS 2 userspace events will be printed. It will also print the path to the directory that will contain the resulting trace (under~/.ros/tracing).# terminal 1cd~/tracing_wssourceinstall/setup.bash ros2trace--session-nameperf-test--listPress enter to start tracing.Step 2: Run


key: chroma:document
string_value:
enter to start tracing.Step 2: Run ApplicationIn a second terminal, source the workspace.# terminal 2cd~/tracing_wssourceinstall/setup.bashThen run theperformance_testexperiment (or your own application). We simply create an experiment with a node publishing ~1 MB messages to another node as fast as possible for 60 seconds using the second highest real-time priority so that we don’t interfere with critical kernel threads. We need to runperformance_testasrootto be able to use real-time priorities.# terminal 2sudo./install/performance_test/lib/performance_test/perf_test-crclcpp-single-threaded-executor-p1-s1-r0-mArray1m--reliabilityRELIABLE--max-runtime60--use-rt-prio98If that last command doesn’t work for you (with an error like: “error while loading shared libraries”), run the slightly-different command below. This is because, for security reasons, we need to manually pass*PATHenvironment variables for some shared libraries to be found (seethis explanation).# terminal


key: chroma:document
string_value:
shared libraries to be found (seethis explanation).# terminal 2sudoenvPATH="$PATH"LD_LIBRARY_PATH="$LD_LIBRARY_PATH"./install/performance_test/lib/performance_test/perf_test-crclcpp-single-threaded-executor-p1-s1-r0-mArray1m--reliabilityRELIABLE--max-runtime60--use-rt-prio98NoteIf you’re not using a real-time kernel, simply run:# terminal 2./install/performance_test/lib/performance_test/perf_test-crclcpp-single-threaded-executor-p1-s1-r0-mArray1m--reliabilityRELIABLE--max-runtime60Step 3: Validate TraceOnce the experiment is done, in the first terminal, press enter again to stop tracing. Usebabeltraceto quickly look at the resulting trace.babeltrace~/.ros/tracing/perf-test|lessThe output of the above command is a human-readable version of the raw Common Trace Format (CTF) data, which is a list of trace events. Each event has a timestamp, an event type, some information on the process that generated the event, and the values of the fields of the given event type.Use the arrow keys to scroll, or pressqto


key: chroma:document
string_value:
the given event type.Use the arrow keys to scroll, or pressqto exit.Next, we will analyze the trace.Analysistracetools_analysisprovides a Python API to easily analyze traces. We can use it in aJupyter notebookwithbokehto plot the data. Thetracetools_analysisrepository contains afew sample notebooks, includingone notebook to analyze subscription callback durations.For this tutorial, we will plot the durations of the subscription callback in the subscriber node.Install Jupyter notebook and bokeh, and then open the sample notebook.pip3installbokeh jupyternotebook~/tracing_ws/src/tracetools_analysis/tracetools_analysis/analysis/callback_duration.ipynbThis will open the notebook in the browser.Replace the value for thepathvariable in the second cell to the path to the trace directory:path='~/.ros/tracing/perf-test'Run the notebook by clicking theRunbutton for each cell. Running the cell that does the trace processing might take a few minutes on the first run, but subsequent runs will be much quicker.You should


key: chroma:document
string_value:
first run, but subsequent runs will be much quicker.You should get a plot that looks similar to this:We can see that most of the callbacks take less than 0.01 ms, but there are some outliers taking over 0.02 or 0.03 ms.ConclusionThis tutorial showed how to install tracing-related tools. Then it showed how to trace aperformance_testexperiment usingros2_tracingand plot the callback durations usingtracetools_analysis.For more trace analyses, take a look at theother sample notebooksand thetracetools_analysis API documentation. Theros2_tracing design documentalso contains a lot of information.


key: chroma:document
string_value:
Code Examples:

Language: unknown

sudoapt

getupdate

sudoapt

getinstall

ybabeltraceros

jazzy

ros2traceros

jazzy

tracetools

analysis

Language: unknown

source/opt/ros/jazzy/setup.bash

ros2runtracetoolsstatus

Language: unknown

cd~/

mkdir

ptracing_ws/srccdtracing_ws/src/

gitclonehttps://gitlab.com/ApexAI/performance_test.git

gitclonehttps://github.com/ros

tracing/tracetools_analysis.git

bjazzycd..

Language: unknown

rosdepupdate

rosdepinstall-

from

pathssrc-

ignore

src

y

Language: unknown

colconbuild-

packages

selectperformance_test-

cmake

args

DPERFORMANCE_TEST_RCLCPP_ENABLED=ON

Language: unknown

# terminal 1cd~/tracing_wssourceinstall/setup.bash

ros2trace-

session

nameperf

test-

list

Language: unknown

# terminal 2cd~/tracing_wssourceinstall/setup.bash

Language: unknown

# terminal 2sudo./install/performance_test/lib/performance_test/perf_test

crclcpp

single

threaded

executor

p1

s1

r0

mArray1m-

reliabilityRELIABLE-

max

runtime60-

use

rt

prio98


key: chroma:document
string_value:
reliabilityRELIABLE-

max

runtime60-

use

rt

prio98

Language: unknown

# terminal 2sudoenvPATH="$PATH"LD_LIBRARY_PATH="$LD_LIBRARY_PATH"./install/performance_test/lib/performance_test/perf_test

crclcpp

single

threaded

executor

p1

s1

r0

mArray1m-

reliabilityRELIABLE-

max

runtime60-

use

rt

prio98

Language: unknown

# terminal 2./install/performance_test/lib/performance_test/perf_test

crclcpp

single

threaded

executor

p1

s1

r0

mArray1m-

reliabilityRELIABLE-

max

runtime60

Language: unknown

babeltrace~/.ros/tracing/perf

test|less

Language: unknown

pip3installbokeh

jupyternotebook~/tracing_ws/src/tracetools_analysis/tracetools_analysis/analysis/callback_duration.ipynb

Language: unknown

path='~/.ros/tracing/perf

test'


key: chroma:document
string_value:
Title: Galactic Geochelone (galactic)

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

Galactic

Geochelone.html

Section: Installation

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


key: chroma:document
string_value:
Galactic Geochelone (galactic)Table of ContentsSupported PlatformsInstallationNew features in this ROS 2 releaseAbility to specify per-logger log levelsAbility to configure logging directory through environment variablesAbility to invokerosidlpipeline outside CMakeExternally configure QoS at start-upPython point_cloud2 utilities availableRViz2 Time Panelros2 topic echo can print serialized dataGet the YAML representation of messagesAbility to load parameter files at runtime through the ros2 commandTools to check for QoS incompatibilitiesUse launch substitutions in parameter filesSupport for unique network flowsRosbag2 New FeaturesChanges since the Foxy releaseDefault RMW changed to Eclipse Cyclone DDSConnext RMW changed to rmw_connextddsLarge improvements in testing and overall qualityrmwament_cmakenav2tf2_ros Python split out of tf2_rostf2_ros Python TransformListener uses global namespacerclcpprclpyrclcpp_actionrosidl_typesupport_introspection_crcl_lifecycle and rclcpp_lifecyclercl_lifecycle and


key: chroma:document
string_value:
and rclcpp_lifecyclercl_lifecycle and rclcpp_lifecycleKnown Issuesros2clirqtrviz2Timeline before the releaseGalactic Geocheloneis the seventh release of ROS 2. What follows is highlights of the important changes and features in Galactic Geochelone since the last release. For a list of all of the changes since Foxy, see thelong form changelog.Supported PlatformsGalactic Geochelone is primarily supported on the following platforms:Tier 1 platforms:Ubuntu 20.04 (Focal):amd64andarm64Windows 10 (Visual Studio 2019):amd64Tier 2 platforms:RHEL 8:amd64Tier 3 platforms:Ubuntu 20.04 (Focal):arm32Debian Bullseye (11):amd64,arm64andarm32OpenEmbedded Thud (2.6) / webOS OSE:arm32andarm64Mac macOS 10.14 (Mojave):amd64For more information about RMW implementations, compiler / interpreter versions, and system dependency versions seeREP 2000.InstallationInstall Galactic GeocheloneNew features in this ROS 2 releaseAbility to specify per-logger log levelsIt is now possible to specify different logging levels for different


key: chroma:document
string_value:
now possible to specify different logging levels for different loggers on the command line:ros2rundemo_nodes_cpptalker--ros-args--log-levelWARN--log-leveltalker:=DEBUGThe above command sets a global log level of WARN, but sets the log level of the talker node messages to DEBUG. The--log-levelcommand-line option can be passed an arbitrary number of times to set different log levels for each logger.Ability to configure logging directory through environment variablesIt is now possible to configure the logging directory through two environment variables:ROS_LOG_DIRandROS_HOME. The logic is as follows:Use$ROS_LOG_DIRifROS_LOG_DIRis set and not empty.Otherwise, use$ROS_HOME/log, using~/.rosforROS_HOMEif not set or if empty.Thus the default value stays the same:~/.ros/log.Related PRs:ros2/rcl_logging#53andros2/launch#460.For example:ROS_LOG_DIR=/tmp/fooros2rundemo_nodes_cpptalkerWill place all logs in/tmp/foo.ROS_HOME=/path/to/homeros2rundemo_nodes_cpptalkerWill place all logs in/path/to/home/log.Ability to


key: chroma:document
string_value:
place all logs in/path/to/home/log.Ability to invokerosidlpipeline outside CMakeIt is now straightforward to invoke therosidlinterface generation pipeline outside CMake. Source code generators and interface definition translators are accessible through a unified command line interface.For example, given aDemomessage in somedemopackage like:mkdir-pdemo/msgcddemo cat<< EOF > msg/Demo.msgstd_msgs/Header headergeometry_msgs/Twist twistgeometry_msgs/Accel accelEOFit is easy to generate C, C++, and Python support source code:rosidlgenerate-ogen-tc-tcpp-tpy-I$(ros2pkgprefix--sharestd_msgs)/..\-I$(ros2pkgprefix--sharegeometry_msgs)/..demomsg/Demo.msgGenerated source code will be put in thegendirectory.One may also translate the message definition to a different format for a third-party code generation tool to consume:rosidltranslate-ogen--toidl-I$(ros2pkgprefix--sharestd_msgs)/..\-I$(ros2pkgprefix--sharegeometry_msgs)/..demomsg/Demo.msgThe translated message definition will be put in thegendirectory.Note that these


key: chroma:document
string_value:
definition will be put in thegendirectory.Note that these tools generate sources but do not build it – that responsibility is still on the caller. This is a first step towards enablingrosidlinterface generation in build systems other than CMake. See thedesign documentfor further reference and next steps.Externally configure QoS at start-upIt is now possible to externally configure the QoS settings for a node at start-up time. QoS settings arenotconfigurable during runtime; they are only configurable at start-up. Node authors must opt-in to enable changing QoS settings at start-up. If the feature is enabled on a node, then QoS settings can be set with ROS parameters when a node first starts.Demos in C++ and Python can be found here.See thedesign document for more details.Note, user code handling parameter changes with registered callbacks should avoid rejecting updates for unknown parameters. It was considered bad practice prior to Galactic, but with externally configurable QoS enabled it will result in a


key: chroma:document
string_value:
with externally configurable QoS enabled it will result in a hard failure.Related PRs:ros2/rclcpp#1408andros2/rclpy#635Python point_cloud2 utilities availableSeveral utilities for interacting withPointCloud2 messagesin Python wereported to ROS 2. These utilities allow one to get a list of points from a PointCloud2 message (read_pointsandread_points_list), and to create a PointCloud2 message from a list of points (create_cloudandcreate_cloud_xyz32).An example of creating PointCloud 2 message, then reading it back:importsensor_msgs_py.point_cloud2fromstd_msgs.msgimportHeaderpointlist=[[0.0,0.1,0.2]]pointcloud=sensor_msgs_py.point_cloud2.create_cloud_xyz32(Header(frame_id='frame'),pointlist)forpointinsensor_msgs_py.point_cloud2.read_points(pointcloud):print(point)RViz2 Time PanelThe Rviz2 Time Panel, which shows the current Wall and ROS time, along with the elapsed Wall and ROS time, has beenported to RViz2. To enable the Time Panel, click on Panels -> Add New Panel, and select “Time”. A panel that looks like


key: chroma:document
string_value:
-> Add New Panel, and select “Time”. A panel that looks like the following will appear:ros2 topic echo can print serialized dataWhen debugging middleware issues, it can be useful to see the raw serialized data that the RMW is sending. The–raw command-line flagwas added toros2topicechoto show this data. To see this in action, run the following commands.Terminal 1:$ros2topicpub/chatterstd_msgs/msg/String"data: 'hello'"Terminal 2:$ros2topicecho--raw/chatter b'\x00\x01\x00\x00\x06\x00\x00\x00hello\x00\x00\x00'---Get the YAML representation of messagesIt is now possible to get a YAML representation of all messages in C++ using theto_yamlfunction. An example of code that prints out the YAML representation:#include<cstdio>#include<std_msgs/msg/string.hpp>intmain(){std_msgs::msg::Stringmsg;msg.data="hello world";printf("%s",rosidl_generator_traits::to_yaml(msg).c_str());return0;}Ability to load parameter files at runtime through the ros2 commandROS 2 has long had the ability to specify parameter values at startup


key: chroma:document
string_value:
has long had the ability to specify parameter values at startup (through command-line arguments or a YAML file), and to dump current parameters out to a file (throughros2paramdump). Galactic adds the ability toload parameter values at runtimefrom a YAML file using theros2paramloadverb. For example:Terminal 1:$ros2rundemo_nodes_cppparameter_blackboardTerminal 2:$ros2paramset/parameter_blackboardfoobar# sets 'foo' parameter to value 'bar'$ros2paramdump/parameter_blackboard# dumps current value of parameters to ./parameter_blackboard.yaml$ros2paramset/parameter_blackboardfoodifferent# sets 'foo' parameter to value 'different'$ros2paramload/parameter_blackboard./parameter_blackboard.yaml# reloads previous state of parameters, 'foo' is back to 'bar'Tools to check for QoS incompatibilitiesBuilt on top of new QoS compatibility check APIs,ros2doctorandrqt_graphcan now detect and report QoS incompatibilities between publishers and subscriptions.Given a publisher and a subscription withincompatible QoS


key: chroma:document
string_value:
a publisher and a subscription withincompatible QoS settings:Terminal 1:$ros2rundemo_nodes_pytalker_qos-n1000# i.e. best_effort publisherTerminal 2:$ros2rundemo_nodes_pylistener_qos--reliable-n1000# i.e. reliable subscriptionros2doctorreports:$ros2doctor--report# ...QOSCOMPATIBILITYLIST topic[type]:/chatter[std_msgs/msg/String]publishernode:talker_qos subscribernode:listener_qos compatibilitystatus:ERROR:Besteffortpublisherandreliablesubscription;# ...whilerqt_graphshows:Related PRs:ros2/ros2cli#621,ros-visualization/rqt_graph#61Use launch substitutions in parameter filesJust likerosparamtags in ROS 1roslaunch,launch_roscan now evaluate substitutions in parameter files.For example, given someparameter_file_with_substitutions.yamllike the following:/**:ros__parameters:launch_date:$(command date)Setallow_subststoTrueto get substitutions evaluated


key: chroma:document
string_value:
date)Setallow_subststoTrueto get substitutions evaluated uponNodelaunch:importlaunchimportlaunch_ros.parameter_descriptionsimportlaunch_ros.actionsdefgenerate_launch_description():returnlaunch.LaunchDescription([launch_ros.actions.Node(package='demo_nodes_cpp',executable='parameter_blackboard',parameters=[launch_ros.parameter_descriptions.ParameterFile(param_file='parameter_file_with_substitutions.yaml',allow_substs=True)])])XML launch files also support this.<launch><nodepkg="demo_nodes_cpp"exec="parameter_blackboard"><paramfrom="parameter_file_with_substitutions.yaml"allow_substs="true"/></node></launch>Related PR:ros2/launch_ros#168Support for unique network flowsApplications may now require UDP/TCP and IP-based RMW implementations to provide uniquenetwork flows(i.e. uniqueDifferentiated Services Code Pointsand/or uniqueIPv6 Flow Labelsand/or unique ports in IP packet headers) for publishers and subscriptions, enabling QoS specifications for these IP streams in network architectures that support such a


key: chroma:document
string_value:
these IP streams in network architectures that support such a feature, like 5G networks.To see this in action, you may run these C++ examples (to be found in theros2/examplesrepository):Terminal 1:ros2runexamples_rclcpp_minimal_publisherpublisher_member_function_with_unique_network_flow_endpointsTerminal 2:ros2runexamples_rclcpp_minimal_subscribersubscriber_member_function_with_unique_network_flow_endpointsSee theUnique Network Flows design documentfor further reference.Rosbag2 New FeaturesSplit recording by timeIn Foxy, you could only split bags as they were recording by the size of the bag, now you can also split by the elapsed time. The following command will split bagfiles into 100-second chunks.ros2bagrecord--all--max-bag-duration100ros2 bag listThis new command lists installed plugins of various types that rosbag2 uses.$ros2bagliststorage rosbag2_v2 sqlite3


key: chroma:document
string_value:
$ros2baglistconverter rosbag_v2_converterCompression implementation is a pluginIn Foxy, rosbag2 compression was hardcoded with a Zstd library implementation. This has been rearchitected so that compression implementations are a plugin, and can be swapped out without modifying the core rosbag2 codebase. The default plugin that ships withros-galactic-rosbag2is still the Zstd plugin - but now more can be released and used, and by selectively installing packages Zstd could be excluded from an installation.Compress per-messageIn Foxy, you could automatically compress each rosbag file as it was split (per-file compression), but now you can also specify per-message compression.ros2bagrecord--all--compression-formatzstd--compression-modemessageRosbag2 Python APIA new packagerosbag2_pyhas been released in Galactic, which provides a Python API. This package is apybind11binding around the C++ API. As of the initial Galactic release, it does not yet expose all functionality available via therosbag2_cppAPI, but it is


key: chroma:document
string_value:
all functionality available via therosbag2_cppAPI, but it is the sole connection for theros2bagCLI tool, so a good deal of functionality is available.performance testing package and performance improvementsA thorough performance analysis project was performed on rosbag2 since the Foxy release. The full initial report is available athttps://github.com/ros2/rosbag2/blob/galactic/rosbag2_performance/rosbag2_performance_benchmarking/docs/rosbag2_performance_improvements.pdf. The packagerosbag2_performance_benchmarkingprovides tools to run performance analyses, especially on recording, which helps us maintain and improve the performance of rosbag2.Following this report, key work was done do improve the performance to a much more usable state for actual robot workflows. To highlight a key metric - in a high bandwidth stress test (200Mbps), the Foxy release dropped up to 70% of messages, whereas the Galactic version was approximately 100% retention. Please see the linked report for more


key: chroma:document
string_value:
100% retention. Please see the linked report for more details.--regexand--excludeoptions for topic selectionThe new recording options--regexand--excludeallow for fine-tuning the topics recorded in a bag, without having to explicitly list all topics. These options may be used together or separately, and in conjunction with--allThe following command will record only topics with “scan” in the name.ros2bagrecord--regex"*scan*"The following command will record all topics except for ones in/my_namespace/ros2bagrecord--all--exclude"/my_namespace/*"ros2bagreindexROS 2 bags are represented by a directory, instead of a single file. This directory contains ametadata.yamlfile, and one or more bag files. When themetadata.yamlfile is lost or missing,ros2bagreindex$bag_dirwill attempt to reconstruct it by reading all the bag files in the directory.Playback time controlNew controls have been added for rosbag2 playback - pause & resume, change rate, and play-next. As of the Galactic release, these controls are exposed


key: chroma:document
string_value:
As of the Galactic release, these controls are exposed only as services on the rosbag2 player node. Development is in progress to expose them to keyboard controls as well inros2bagplay, but until then a user application with buttons or keyboard controls may be trivially implemented to call these services.# In one shell$ros2bagplaymy_bag# In another shell$ros2servicelist-t /rosbag2_player/get_rate[rosbag2_interfaces/srv/GetRate]/rosbag2_player/is_paused[rosbag2_interfaces/srv/IsPaused]/rosbag2_player/pause[rosbag2_interfaces/srv/Pause]/rosbag2_player/play_next[rosbag2_interfaces/srv/PlayNext]/rosbag2_player/resume[rosbag2_interfaces/srv/Resume]/rosbag2_player/set_rate[rosbag2_interfaces/srv/SetRate]/rosbag2_player/toggle_paused[rosbag2_interfaces/srv/TogglePaused]# Check if playback is paused$ros2servicecall/rosbag2_player/is_pausedrosbag2_interfaces/IsPaused# Pause playback$ros2servicecall/rosbag2_player/pauserosbag2_interfaces/Pause# Resume


key: chroma:document
string_value:
Resume playback$ros2servicecall/rosbag2_player/resumerosbag2_interfaces/Resume# Change the paused state of playback to its opposite. If playing, pauses. If paused, resumes.$ros2servicecall/rosbag2_player/toggle_pausedrosbag2_interfaces/TogglePaused# Get the current playback rate$ros2servicecall/rosbag2_player/get_rate# Set the current playback rate (must be > 0)$ros2servicecall/rosbag2_player/set_raterosbag2_interfaces/SetRate"rate: 0.1"# Play a single next message (only works while paused)$ros2servicecall/rosbag2_player/play_nextrosbag2_interfaces/PlayNextPlayback publishes /clockRosbag2 can also dictate “simulation time” by publishing to the/clocktopic during playback. The following commands will publish the clock message at a regular interval.# Publish at default rate - 40Hzros2bagplaymy_bag--clock# Publish at specific rate - 100Hzros2bagplaymy_bag--clock100Changes since the Foxy releaseDefault RMW changed to Eclipse Cyclone DDSDuring the Galactic development process, the ROS 2 Technical Steering


key: chroma:document
string_value:
the Galactic development process, the ROS 2 Technical Steering Committeevotedto change the default ROS middleware (RMW) toEclipse Cyclone DDSproject ofEclipse Foundation. Without any configuration changes, users will get Eclipse Cyclone DDS by default. Fast DDS and Connext are still Tier-1 supported RMW vendors, and users can opt-in to use one of these RMWs at their discretion by using theRMW_IMPLEMENTATIONenvironment variable. See theWorking with multiple RMW implementations guidefor more information.Connext RMW changed to rmw_connextddsA new RMW for Connext calledrmw_connextddswas merged for Galactic. This RMW has better performance and fixes many of the issues with the older RMWrmw_connext_cpp.Large improvements in testing and overall qualityGalactic contains many changes that fix race conditions, plug memory leaks, and fix user reported problems. Besides these changes, there was a concerted effort during Galactic development to improve overall quality of the system by implementingREP 2004.


key: chroma:document
string_value:
improve overall quality of the system by implementingREP 2004. Therclcpppackage and all of its dependencies (which include most of the ROS 2 non-Python core packages) were brought up toQuality Level 1by:Having a version policy (QL1 requirement 1)Having a documented change control process (QL1 requirement 2)Documenting all features and public APIs (QL1 requirement 3)Adding many additional tests (QL1 requirement 4):System tests for all featuresUnit tests for all public APIsNightly performance testsCode coverage at 95%Having all runtime dependencies of packages be at least as high as the package (QL1 requirement 5)Supporting all of the REP-2000 platforms (QL1 requirement 6)Having a vulnerability disclosure policy (QL1 requirement 7)rmwNew API for checking QoS profile compatibilityrmw_qos_profile_check_compatibleis a new function for checking the compatibility of two QoS profiles.RMW vendors should implement this API for QoS debugging and introspection features in tools such asrqt_graphto work


key: chroma:document
string_value:
and introspection features in tools such asrqt_graphto work correctly.Related PR:ros2/rmw#299ament_cmakeament_install_python_package()now installs a Python eggBy installing a flat Python egg, Python packages installed usingament_install_python_package()can be discovered using modules such aspkg_resourcesand`importlib.metadata. Also, additional metadata can be provided in asetup.cfgfile (including entry points).Related PR:ament/ament_cmake#326ament_target_dependencies()handles SYSTEM dependenciesSome package dependencies can now be marked as SYSTEM dependencies, helping to cope with warnings in external code. Typically, SYSTEM dependencies are also excluded from dependency calculations – use them with care.Related PR:ament/ament_cmake#297nav2Changes include, but are not limited to, a number of stability improvements, new plugins, interface changes, costmap filters. SeeMigration Guidesfor full listtf2_ros Python split out of tf2_rosThe Python code that used to live in tf2_ros has been moved into its own


key: chroma:document
string_value:
code that used to live in tf2_ros has been moved into its own package named tf2_ros_py. Any existing Python code that depends on tf2_ros will continue to work, but the package.xml of those packages should be amended toexec_dependon tf2_ros_py.tf2_ros Python TransformListener uses global namespaceThe PythonTransformListenernow subscribes to/tfand/tf_staticin the global namespace. Previously, it was susbcribing in the node’s namespace. This means that the node’s namespace will no longer have an effect on the/tfand/tf_staticsubscriptions.For example:ros2runtf2_rostf2_echo--ros-args-r__ns:=/test--odombase_linkwill subscribe to/tfand/tf_static, asros2topiclistwill show.Related PR:ros2/geometry2#390rclcppChange in spin_until_future_complete template parametersThe first template parameter ofExecutor::spin_until_future_completewas the future result typeResultT, and the method only accepted astd::shared_future<ResultT>. In order to accept other types of futures (e.g.:std::future), that parameter was changed to the


key: chroma:document
string_value:
futures (e.g.:std::future), that parameter was changed to the future type itself.In places where aspin_until_future_completecall was relying on template argument deduction, no change is needed. If not, this is an example diff:std::shared_future<MyResultT> future; ...-executor.spin_until_future_complete<MyResultT>(future);+executor.spin_until_future_complete<std::shared_future<MyResultT>>(future);For more details, seeros2/rclcpp#1160. For an example of the needed changes in user code, seeros-visualization/interactive_markers#72.Change in default/clocksubscription QoS profileThe default was changed from a reliable communication with history depth 10 to a best effort communication with history depth 1. Seeros2/rclcpp#1312.Waitable APIWaitable API was modified to avoid issues with theMultiThreadedExecutor. This only affects users implementing a custom waitable. Seeros2/rclcpp#1241for more details.Change inrclcpp’s logging macrosPreviously, the logging macros were vulnerable to aformat string attack, where the


key: chroma:document
string_value:
macros were vulnerable to aformat string attack, where the format string is evaluated and can potentially execute code, read the stack, or cause a segmentation fault in the running program. To address this security issue, the logging macro now accepts only string literals for it’s format string argument.If you previously had code like:constchar*my_const_char_stringformat="Foo";RCLCPP_DEBUG(get_logger(),my_const_char_string);you should now replace it with:constchar*my_const_char_stringformat="Foo";RCLCPP_DEBUG(get_logger(),"%s",my_const_char_string);or:RCLCPP_DEBUG(get_logger(),"Foo");This change removes some convenience from the logging macros, asstd::strings are no longer accepted as the format argument.If you previously had code with no format arguments like:std::stringmy_std_string="Foo";RCLCPP_DEBUG(get_logger(),my_std_string);you should now replace it with:std::stringmy_std_string="Foo";RCLCPP_DEBUG(get_logger(),"%s",my_std_string.c_str());NoteIf you are using astd::stringas a format string with format


key: chroma:document
string_value:
you are using astd::stringas a format string with format arguments, converting that string to achar*and using it as the format string will yield a format security warning. That’s because the compiler has no way at compile to introspect into thestd::stringto verify the arguments.  To avoid the security warning, we recommend you build the string manually and pass it in with no format arguments like the previous example.std::stringstreamtypes are still accepted as arguments to the stream logging macros. Seeros2/rclcpp#1442for more details.Parameter types are now static by defaultPreviously, the type of a parameter could be changed when a parameter was set. For example, if a parameter was declared as an integer, a later call to set the parameter could change that type to a string. This behavior could lead to bugs, and is rarely what the user wants. As of Galactic parameter types are static by default, and attempts to change the type will fail. If the previous dynamic behavior is desired, there is an mechanism


key: chroma:document
string_value:
the previous dynamic behavior is desired, there is an mechanism to opt it in (see the code below).// declare integer parameter with default value, trying to set it to a different type will fail.node->declare_parameter("my_int",5);// declare string parameter with no default and mandatory user provided override.// i.e. the user must pass a parameter file setting it or a command line rule -p <param_name>:=<value>node->declare_parameter("string_mandatory_override",rclcpp::PARAMETER_STRING);// Conditionally declare a floating point parameter with a mandatory override.// Useful when the parameter is only needed depending on other conditions and no default is reasonable.if(mode=="modeA"){node->declare_parameter("conditionally_declare_double_parameter",rclcpp::PARAMETER_DOUBLE);}// You can also get the old dynamic typing behavior if you want:rcl_interfaces::msg::ParameterDescriptordescriptor;descriptor.dynamic_typing=true;node->declare_parameter("dynamically_typed_param",rclcpp::ParameterValue{},descriptor);For more


key: chroma:document
string_value:
more details seehttps://github.com/ros2/rclcpp/blob/galactic/rclcpp/doc/notes_on_statically_typed_parameters.md.New API for checking QoS profile compatibilityqos_check_compatibleis a new function for checking the compatibility of two QoS profiles.Related PR:ros2/rclcpp#1554rclpyRemoval of deprecated Node.set_parameters_callbackThe methodNode.set_parameters_callbackwasdeprecated in ROS Foxyand has beenremoved in ROS Galactic. UseNode.add_on_set_parameters_callback()instead. Here is some example code using it.importrclpyimportrclpy.nodefromrcl_interfaces.msgimportParameterTypefromrcl_interfaces.msgimportSetParametersResultrclpy.init()node=rclpy.node.Node('callback_example')node.declare_parameter('my_param','initial value')defon_parameter_event(parameter_list):forparameterinparameter_list:node.get_logger().info(f'Got{parameter.name}={parameter.value}')returnSetParametersResult(successful=True)node.add_on_set_parameters_callback(on_parameter_event)rclpy.spin(node)Run this command to see the parameter callback


key: chroma:document
string_value:
this command to see the parameter callback in action.ros2paramset/callback_examplemy_param"Hello World"Parameter types are now static by defaultIn Foxy and earlier a call to set a parameter could change its type. As of Galactic parameter types are static and cannot be changed by default. If the previous behavior is desired, then setdynamic_typingto true in the parameter descriptor. Here is an example.importrclpyimportrclpy.nodefromrcl_interfaces.msgimportParameterDescriptorrclpy.init()node=rclpy.node.Node('static_param_example')node.declare_parameter('static_param','initial value')node.declare_parameter('dynamic_param','initial value',descriptor=ParameterDescriptor(dynamic_typing=True))rclpy.spin(node)Run these commands to see how statically and dynamically typed parameters are different.$ros2paramset/static_param_exampledynamic_param42Set parameter successful$ros2paramset/static_param_examplestatic_param42Setting parameter failed: Wrong parameter type, expected 'Type.STRING' got 'Type.INTEGER'For more


key: chroma:document
string_value:
type, expected 'Type.STRING' got 'Type.INTEGER'For more details seehttps://github.com/ros2/rclcpp/blob/galactic/rclcpp/doc/notes_on_statically_typed_parameters.md.New API for checking QoS profile compatibilityrclpy.qos.qos_check_compatibleisa new functionfor checking the compatibility of two QoS profiles. If the profiles are compatible, then a publisher and subscriber using them will be able to talk to each other.importrclpy.qospublisher_profile=rclpy.qos.qos_profile_sensor_datasubscription_profile=rclpy.qos.qos_profile_parameter_eventsprint(rclpy.qos.qos_check_compatible(publisher_profile,subscription_profile))$python3qos_check_compatible_example.py(QoSCompatibility.ERROR, 'ERROR: Best effort publisher and reliable subscription;')rclcpp_actionAction client goal response callback signature changedThe goal response callback should now take a shared pointer to a goal handle, instead of a future.Forexample, old signature:voidgoal_response_callback(std::shared_future<GoalHandleFibonacci::SharedPtr>future)New


key: chroma:document
string_value:
signature:voidgoal_response_callback(GoalHandleFibonacci::SharedPtrgoal_handle)Related PR:ros2/rclcpp#1311rosidl_typesupport_introspection_cAPI break in function that gets an element from an arrayThe signature of the function was changed because it was semantically different to all the other functions used to get an element from an array or sequence. This only affects authors of rmw implementations using the introspection typesupport.For further details, seeros2/rosidl#531.rcl_lifecycle and rclcpp_lifecycleRCL’s lifecycle state machine gets new init APIThe lifecycle state machine in rcl_lifecycle was modified to expect a newly introduced options struct, combining general configurations for the state machine. The option struct allows to indicate whether the state machine shall be initialized with default values, whether its attached services are active and which allocator to be


key: chroma:document
string_value:
its attached services are active and which allocator to be used.rcl_ret_trcl_lifecycle_state_machine_init(rcl_lifecycle_state_machine_t*state_machine,rcl_node_t*node_handle,constrosidl_message_type_support_t*ts_pub_notify,constrosidl_service_type_support_t*ts_srv_change_state,constrosidl_service_type_support_t*ts_srv_get_state,constrosidl_service_type_support_t*ts_srv_get_available_states,constrosidl_service_type_support_t*ts_srv_get_available_transitions,constrosidl_service_type_support_t*ts_srv_get_transition_graph,constrcl_lifecycle_state_machine_options_t*state_machine_options);RCL’s lifecycle state machine stores allocator instanceThe options struct (discussed above) entails an instance of the allocator being used for initializing the state machine. This options struct and there the embodied allocator are being stored within the lifecycle state machine. As a direct consequence, thercl_lifecycle_finifunctionno longer expects an allocator in its fini function but rather uses the allocator set in the


key: chroma:document
string_value:
in its fini function but rather uses the allocator set in the options struct for deallocating its internal data structures.rcl_ret_trcl_lifecycle_state_machine_fini(rcl_lifecycle_state_machine_t*state_machine,rcl_node_t*node_handle);RCLCPP’s lifecycle node exposes option to not instantiate servicesIn order to use rclcpp’s lifecycle nodes without exposing its internal services such aschange_state,get_stateet. al., the constructor of a lifecycle node has a newly introduced parameter indicating whether or not the services shall be available. This boolean flag is set to true by default, not requiring any changes to existing API if not wished.explicitLifecycleNode(conststd::string&node_name,constrclcpp::NodeOptions&options=rclcpp::NodeOptions(),boolenable_communication_interface=true);Related PRs:ros2/rcl#882andros2/rclcpp#1507rcl_lifecycle and rclcpp_lifecycleRecording - Split by timeKnown Issuesros2cliDaemon slows down CLI on WindowsAs a workaround, CLI commands may be used without a daemon


key: chroma:document
string_value:
a workaround, CLI commands may be used without a daemon e.g.:ros2topiclist--no-daemonIssue is tracked byros2/ros2cli#637.rqtSome rqt_bag icons are missingThe icons to “Zoom In”, “Zoom Out”, “Zoom Home”, and “Toggle Thumbnails” are missing inrqt_bag. The issue is tracked inros-visualization/rqt_bag#102Most rqt utilities don’t work standalone on WindowsLaunching the rqt utilities “standalone” on Windows (likeros2runrqt_graphrqt_graph) generally doesn’t work. The workaround is to launch the rqt container process (rqt), and then insert the plugins to be used.rviz2RViz2 panel close buttons are blankThe upper right-hand corner of every RViz2 panel should contain an “X” to allow one to close the panel. Those buttons are there, but the “X” inside of them is missing on all platforms. The issue is being tracked inros2/rviz2#692.Timeline before the releaseMon. March 22, 2021 - AlphaPreliminary testing and stabilization of ROS Core[1]packages.Mon. April 5, 2021 - FreezeAPI and feature freeze for ROS


key: chroma:document
string_value:
April 5, 2021 - FreezeAPI and feature freeze for ROS Core[1]packages in Rolling Ridley. Note that this includesrmw, which is a recursive dependency ofros_core. Only bug fix releases should be made after this point. New packages can be released independently.Mon. April 19, 2021 - BranchBranch from Rolling Ridley.rosdistrois reopened for Rolling PRs for ROS Core[1]packages. Galactic development shifts fromros-rolling-*packages toros-galactic-*packages.Mon. April 26, 2021 - BetaUpdated releases of ROS Desktop[2]packages available. Call for general testing.Mon. May 17, 2021 - RCRelease Candidate packages are built.Updated releases of ROS Desktop[2]packages available.Thu. May 20, 2021 - Distro FreezeFreeze rosdistro. No PRs for Galactic on therosdistrorepo will be merged (reopens after the release announcement).Sun. May 23, 2021 - General AvailabilityRelease announcement.rosdistrois reopened for Galactic PRs.[1](1,2,3)Theros_corevariant is described inREP 2001 (ros-core).[2](1,2)Thedesktopvariant is described


key: chroma:document
string_value:
Code Examples:

Language: unknown

ros2rundemo_nodes_cpptalker-

ros

args-

log

levelWARN-

log

leveltalker:=DEBUG

Language: unknown

ROS_LOG_DIR=/tmp/fooros2rundemo_nodes_cpptalker

Language: unknown

ROS_HOME=/path/to/homeros2rundemo_nodes_cpptalker

Language: unknown mkdir-pdemo/msgcddemo cat<< EOF > msg/Demo.msgstd_msgs/Header headergeometry_msgs/Twist twistgeometry_msgs/Accel accelEOF

Language: unknown

rosidlgenerate

ogen

tc

tcpp

tpy

I$(ros2pkgprefix-

sharestd_msgs)/..\

I$(ros2pkgprefix-

sharegeometry_msgs)/..demomsg/Demo.msg

Language: unknown

rosidltranslate

ogen-

toidl

I$(ros2pkgprefix-

sharestd_msgs)/..\

I$(ros2pkgprefix-

sharegeometry_msgs)/..demomsg/Demo.msg

Language: unknown

importsensor_msgs_py.point_cloud2fromstd_msgs.msgimportHeaderpointlist=[[0.0,0.1,0.2]]pointcloud=sensor_msgs_py.point_cloud2.create_cloud_xyz32(Header(frame_id='frame'),pointlist)forpointinsensor_msgs_py.point_cloud2.read_points(pointcloud):print(point)

Language: unknown


key: chroma:document
string_value:
Language: unknown

$ros2topicpub/chatterstd_msgs/msg/String"data: 'hello'"

Language: unknown

$ros2topicecho-

raw/chatter

b'\x00\x01\x00\x00\x06\x00\x00\x00hello\x00\x00\x00'---

Language: unknown

#include<cstdio>#include<std_msgs/msg/string.hpp>intmain(){std_msgs::msg::Stringmsg;msg.data="hello world";printf("%s",rosidl_generator_traits::to_yaml(msg).c_str());return0;}

Language: unknown

$ros2rundemo_nodes_cppparameter_blackboard

Language: unknown $ros2paramset/parameter_blackboardfoobar# sets 'foo' parameter to value 'bar'$ros2paramdump/parameter_blackboard# dumps current value of parameters to ./parameter_blackboard.yaml$ros2paramset/parameter_blackboardfoodifferent# sets 'foo' parameter to value 'different'$ros2paramload/parameter_blackboard./parameter_blackboard.yaml# reloads previous state of parameters, 'foo' is back to 'bar'

Language: unknown

$ros2rundemo_nodes_pytalker_qos

n1000# i.e. best_effort publisher

Language: unknown

$ros2rundemo_nodes_pylistener_qos-

reliable


key: chroma:document
string_value:
$ros2rundemo_nodes_pylistener_qos-

reliable

n1000# i.e. reliable subscription

Language: unknown

$ros2doctor-

report# ...QOSCOMPATIBILITYLIST

topic[type]:/chatter[std_msgs/msg/String]publishernode:talker_qos

subscribernode:listener_qos

compatibilitystatus:ERROR:Besteffortpublisherandreliablesubscription;# ...

Language: unknown

/*

:ros__parameters:launch_date:$(command date)

Language: unknown

importlaunchimportlaunch_ros.parameter_descriptionsimportlaunch_ros.actionsdefgenerate_launch_description():returnlaunch.LaunchDescription([launch_ros.actions.Node(package='demo_nodes_cpp',executable='parameter_blackboard',parameters=[launch_ros.parameter_descriptions.ParameterFile(param_file='parameter_file_with_substitutions.yaml',allow_substs=True)])])

Language: unknown

<launch><nodepkg="demo_nodes_cpp"exec="parameter_blackboard"><paramfrom="parameter_file_with_substitutions.yaml"allow_substs="true"/></node></launch>

Language: unknown


key: chroma:document
string_value:
Language: unknown

ros2runexamples_rclcpp_minimal_publisherpublisher_member_function_with_unique_network_flow_endpoints

Language: unknown

ros2runexamples_rclcpp_minimal_subscribersubscriber_member_function_with_unique_network_flow_endpoints

Language: unknown

ros2bagrecord-

all-

max

bag

duration100

Language: unknown

$ros2bagliststorage

rosbag2_v2

sqlite3

$ros2baglistconverter

rosbag_v2_converter

Language: unknown

ros2bagrecord-

all-

compression

formatzstd-

compression

modemessage

Language: unknown

ros2bagrecord-

regex"

scan

"

Language: unknown

ros2bagrecord-

all-

exclude"/my_namespace/

"


key: chroma:document
string_value:
Language: unknown # In one shell$ros2bagplaymy_bag# In another shell$ros2servicelist-t /rosbag2_player/get_rate[rosbag2_interfaces/srv/GetRate]/rosbag2_player/is_paused[rosbag2_interfaces/srv/IsPaused]/rosbag2_player/pause[rosbag2_interfaces/srv/Pause]/rosbag2_player/play_next[rosbag2_interfaces/srv/PlayNext]/rosbag2_player/resume[rosbag2_interfaces/srv/Resume]/rosbag2_player/set_rate[rosbag2_interfaces/srv/SetRate]/rosbag2_player/toggle_paused[rosbag2_interfaces/srv/TogglePaused]# Check if playback is paused$ros2servicecall/rosbag2_player/is_pausedrosbag2_interfaces/IsPaused# Pause playback$ros2servicecall/rosbag2_player/pauserosbag2_interfaces/Pause# Resume playback$ros2servicecall/rosbag2_player/resumerosbag2_interfaces/Resume# Change the paused state of playback to its opposite. If playing, pauses. If paused, resumes.$ros2servicecall/rosbag2_player/toggle_pausedrosbag2_interfaces/TogglePaused# Get the current playback rate$ros2servicecall/rosbag2_player/get_rate# Set the current playback rate (must be >


key: chroma:document
string_value:
Set the current playback rate (must be > 0)$ros2servicecall/rosbag2_player/set_raterosbag2_interfaces/SetRate"rate: 0.1"# Play a single next message (only works while paused)$ros2servicecall/rosbag2_player/play_nextrosbag2_interfaces/PlayNext


key: chroma:document
string_value:
Language: unknown # Publish at default rate - 40Hzros2bagplaymy_bag--clock# Publish at specific rate - 100Hzros2bagplaymy_bag--clock100

Language: unknown

ros2runtf2_rostf2_echo-

ros

args

r__ns:=/test-

odombase_link

Language: unknown

std::shared_future<MyResultT> future;

...

executor.spin_until_future_complete<MyResultT>(future);+executor.spin_until_future_complete<std::shared_future<MyResultT>>(future);

Language: unknown

constchar

my_const_char_stringformat="Foo";RCLCPP_DEBUG(get_logger(),my_const_char_string);

Language: unknown

constchar

my_const_char_stringformat="Foo";RCLCPP_DEBUG(get_logger(),"%s",my_const_char_string);

Language: unknown

RCLCPP_DEBUG(get_logger(),"Foo");

Language: unknown

std::stringmy_std_string="Foo";RCLCPP_DEBUG(get_logger(),my_std_string);

Language: unknown

std::stringmy_std_string="Foo";RCLCPP_DEBUG(get_logger(),"%s",my_std_string.c_str());


key: chroma:document
string_value:
Language: unknown // declare integer parameter with default value, trying to set it to a different type will fail.node->declare_parameter("my_int",5);// declare string parameter with no default and mandatory user provided override.// i.e. the user must pass a parameter file setting it or a command line rule -p <param_name>:=<value>node->declare_parameter("string_mandatory_override",rclcpp::PARAMETER_STRING);// Conditionally declare a floating point parameter with a mandatory override.// Useful when the parameter is only needed depending on other conditions and no default is reasonable.if(mode=="modeA"){node->declare_parameter("conditionally_declare_double_parameter",rclcpp::PARAMETER_DOUBLE);}// You can also get the old dynamic typing behavior if you want:rcl_interfaces::msg::ParameterDescriptordescriptor;descriptor.dynamic_typing=true;node->declare_parameter("dynamically_typed_param",rclcpp::ParameterValue{},descriptor);

Language: unknown


key: chroma:document
string_value:
Language: unknown

importrclpyimportrclpy.nodefromrcl_interfaces.msgimportParameterTypefromrcl_interfaces.msgimportSetParametersResultrclpy.init()node=rclpy.node.Node('callback_example')node.declare_parameter('my_param','initial value')defon_parameter_event(parameter_list):forparameterinparameter_list:node.get_logger().info(f'Got{parameter.name}={parameter.value}')returnSetParametersResult(successful=True)node.add_on_set_parameters_callback(on_parameter_event)rclpy.spin(node)

Language: unknown

ros2paramset/callback_examplemy_param"Hello World"

Language: unknown

importrclpyimportrclpy.nodefromrcl_interfaces.msgimportParameterDescriptorrclpy.init()node=rclpy.node.Node('static_param_example')node.declare_parameter('static_param','initial value')node.declare_parameter('dynamic_param','initial value',descriptor=ParameterDescriptor(dynamic_typing=True))rclpy.spin(node)


key: chroma:document
string_value:
Language: unknown $ros2paramset/static_param_exampledynamic_param42Set parameter successful$ros2paramset/static_param_examplestatic_param42Setting parameter failed: Wrong parameter type, expected 'Type.STRING' got 'Type.INTEGER'

Language: unknown

importrclpy.qospublisher_profile=rclpy.qos.qos_profile_sensor_datasubscription_profile=rclpy.qos.qos_profile_parameter_eventsprint(rclpy.qos.qos_check_compatible(publisher_profile,subscription_profile))

Language: unknown $python3qos_check_compatible_example.py(QoSCompatibility.ERROR, 'ERROR: Best effort publisher and reliable subscription;')

Language: unknown

voidgoal_response_callback(std::shared_future<GoalHandleFibonacci::SharedPtr>future)

Language: unknown

voidgoal_response_callback(GoalHandleFibonacci::SharedPtrgoal_handle)

Language: unknown

rcl_ret_trcl_lifecycle_state_machine_init(rcl_lifecycle_state_machine_t

state_machine,rcl_node_t

node_handle,constrosidl_message_type_support_t

ts_pub_notify,constrosidl_service_type_support_t


key: chroma:document
string_value:
ts_pub_notify,constrosidl_service_type_support_t

ts_srv_change_state,constrosidl_service_type_support_t

ts_srv_get_state,constrosidl_service_type_support_t

ts_srv_get_available_states,constrosidl_service_type_support_t

ts_srv_get_available_transitions,constrosidl_service_type_support_t

ts_srv_get_transition_graph,constrcl_lifecycle_state_machine_options_t

state_machine_options);

Language: unknown

rcl_ret_trcl_lifecycle_state_machine_fini(rcl_lifecycle_state_machine_t

state_machine,rcl_node_t

node_handle);

Language: unknown

explicitLifecycleNode(conststd::string&node_name,constrclcpp::NodeOptions&options=rclcpp::NodeOptions(),boolenable_communication_interface=true);

Language: unknown

ros2topiclist-

no

daemon


key: chroma:document
string_value:
Title: Setting up a Reset Handler URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Simulators/Webots/Simulation-Reset-Handler.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Setting up a Reset HandlerGoal:Extend a robot simulation with a reset handler to restart nodes when the reset button of Webots is pressed.Tutorial level:AdvancedTime:10 minutesContentsBackgroundPrerequisitesReset Handler for Simple Cases (Controllers Only)Reset Handler for Multiple Nodes (No Shutdown Required)Reset Handler Requiring Node ShutdownSummaryBackgroundIn this tutorial, you will learn how to implement a reset handler in a robot simulation using Webots. The Webots reset button reverts the world to the initial state and restarts controllers. It is convenient as it quickly resets the simulation, but in the context of ROS 2, robot controllers are not started again making the simulation stop. The reset handler allows you to restart specific nodes or perform additional actions when the reset button in Webots is pressed. This can be useful for scenarios where you need to reset the state of your simulation or restart specific components without completely restarting the complete ROS


key: chroma:document
string_value:
components without completely restarting the complete ROS system.PrerequisitesBefore proceeding with this tutorial, make sure you have completed the following:Understanding of ROS 2 nodes and topics covered in the beginnerTutorials.Knowledge of Webots and ROS 2 and its interface package.Familiarity withSetting up a robot simulation (Basic).Reset Handler for Simple Cases (Controllers Only)In the launch file of your package, add therespawnparameter.defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}],# Every time one resets the simulation the controller is automatically respawnedrespawn=True)# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))returnLaunchDescription([webots,robot_driver])On reset, Webots kills all driver nodes. Therefore, to start them again after reset, you should set therespawnproperty of the driver node toTrue. It will ensure driver nodes are up and running


key: chroma:document
string_value:
node toTrue. It will ensure driver nodes are up and running after the reset.Reset Handler for Multiple Nodes (No Shutdown Required)If you have some other nodes that have to be started along with the driver node (e.g.ros2_controlnodes), then you can use theOnProcessExitevent handler:defget_ros2_control_spawners(*args):# Declare here all nodes that must be restarted at simulation resetros_control_node=Node(package='controller_manager',executable='spawner',arguments=['diffdrive_controller'])return[ros_control_node]defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}],# Every time one resets the simulation the controller is automatically respawnedrespawn=True)# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))# Declare the reset handler that respawns nodes when robot_driver


key: chroma:document
string_value:
Declare the reset handler that respawns nodes when robot_driver exitsreset_handler=launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=robot_driver,on_exit=get_ros2_control_spawners,))returnLaunchDescription([webots,robot_driver,reset_handler]+get_ros2_control_spawners())It is not possible to use therespawnproperty on theros2_controlnode, as the spawner exits during launch time and not when the simulation is reset. Instead we should declare a list of nodes in a function (e.g.get_ros2_control_spawners). The nodes of this list are started along other nodes when executing the launch file. With thereset_handler, the function is also declared as action to start when therobot_drivernode exits, which corresponds to the moment when the simulation is reset in the Webots interface. Therobot_drivernode still has therespawnproperty set toTrue, so that it gets restarted along withros2_controlnodes.Reset Handler Requiring Node ShutdownWith the current ROS 2 launch API,


key: chroma:document
string_value:
Requiring Node ShutdownWith the current ROS 2 launch API, there is no way to make the reset work in launch files where nodes need to be shutdown before the restart (e.g.Nav2orRViz). The reason is that currently, ROS 2 doesn’t allow to shutdown specific nodes from a launch file. There is a solution, but it requires to manually restart nodes after pushing the reset button.Webots needs to be started in a specific launch file without other nodes.defgenerate_launch_description():# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))returnLaunchDescription([webots])A second launch file must be started from another process. This launch file contains all other nodes, including robot controllers/plugins, Navigation2 nodes, RViz, state publishers,


key: chroma:document
string_value:
controllers/plugins, Navigation2 nodes, RViz, state publishers, etc.defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}])ros_control_node=Node(package='controller_manager',executable='spawner',arguments=['diffdrive_controller'])nav2_node=IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('nav2_bringup'),'launch','bringup_launch.py')),launch_arguments=[('map',nav2_map),('params_file',nav2_params),],)rviz=Node(package='rviz2',executable='rviz2',output='screen')# Declare the handler that shuts all nodes down when robot_driver exitsshutdown_handler=launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=robot_driver,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))returnLaunchDescription([robot_driver,ros_control_node,nav2_node,rviz,shutdown_handler])The second launch file contains a handler that triggers a shutdown


key: chroma:document
string_value:
second launch file contains a handler that triggers a shutdown event when the driver node exits (which is the case when the simulation is reset). This second launch file must be manually restarted from the command line after pressing the reset button.SummaryIn this tutorial, you learned how to implement a reset handler in a robot simulation using Webots. The reset handler allows you to restart specific nodes or perform additional actions when the reset button in Webots is pressed. You explored different approaches based on the complexity of your simulation and the requirements of your nodes.


key: chroma:document
string_value:
Code Examples:

Language: unknown defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}],# Every time one resets the simulation the controller is automatically respawnedrespawn=True)# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))returnLaunchDescription([webots,robot_driver])


key: chroma:document
string_value:
Language: unknown defget_ros2_control_spawners(*args):# Declare here all nodes that must be restarted at simulation resetros_control_node=Node(package='controller_manager',executable='spawner',arguments=['diffdrive_controller'])return[ros_control_node]defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}],# Every time one resets the simulation the controller is automatically respawnedrespawn=True)# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))# Declare the reset handler that respawns nodes when robot_driver exitsreset_handler=launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=robot_driver,on_exit=get_ros2_control_spawners,))returnLaunchDescription([webots,robot_driver,reset_handler]+get_ros2_control_spawners())

Language: unknown


key: chroma:document
string_value:
Language: unknown

defgenerate_launch_description():# Starts Webotswebots=WebotsLauncher(world=PathJoinSubstitution([package_dir,'worlds',world]))returnLaunchDescription([webots])


key: chroma:document
string_value:
Language: unknown defgenerate_launch_description():robot_driver=WebotsController(robot_name='my_robot',parameters=[{'robot_description':robot_description_path}])ros_control_node=Node(package='controller_manager',executable='spawner',arguments=['diffdrive_controller'])nav2_node=IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('nav2_bringup'),'launch','bringup_launch.py')),launch_arguments=[('map',nav2_map),('params_file',nav2_params),],)rviz=Node(package='rviz2',executable='rviz2',output='screen')# Declare the handler that shuts all nodes down when robot_driver exitsshutdown_handler=launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=robot_driver,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))returnLaunchDescription([robot_driver,ros_control_node,nav2_node,rviz,shutdown_handler])


key: chroma:document
string_value:
Title: Implementing a custom memory allocator URL: https://docs.ros.org/en/jazzy/Tutorials/Advanced/Allocator-Template-Tutorial.html Section: Installation --------------------------------------------------------------------------------


key: chroma:document
string_value:
Implementing a custom memory allocatorGoal:This tutorial will show how to use a custom memory allocator when writing ROS 2 C++ code.Tutorial level:AdvancedTime:20 minutesTable of ContentsBackgroundWriting an allocatorWriting an example mainPassing an allocator to the intra-process pipelineTesting and verifying the codeThe TLSF allocatorThis tutorial will teach you how to integrate a custom allocator for publishers and subscribers so that the default heap allocator is never called while your ROS nodes are executing. The code for this tutorial is availablehere.BackgroundSuppose you want to write real-time safe code, and you’ve heard about the many dangers of callingnewduring the real-time critical section, because the default heap allocator on most platforms is nondeterministic.By default, many C++ standard library structures will implicitly allocate memory as they grow, such asstd::vector. However, these data structures also accept an “Allocator” template argument. If you specify a custom allocator to one


key: chroma:document
string_value:
template argument. If you specify a custom allocator to one of these data structures, it will use that allocator instead of the system allocator to grow or shrink the data structure. Your custom allocator could have a pool of memory preallocated on the stack, which might be better suited to real-time applications.In the ROS 2 C++ client library (rclcpp), we are following a similar philosophy to the C++ standard library. Publishers, subscribers, and the Executor accept an Allocator template parameter that controls allocations made by that entity during execution.Writing an allocatorTo write an allocator compatible with ROS 2’s allocator interface, your allocator must be compatible with the C++ standard library allocator interface.Since C++17, the standard library provides something calledstd::pmr::memory_resource. This is a class that can be derived from to create a custom allocator that fulfills a minimum set of requirements.For example, the following declaration for a custom memory resource fulfills the


key: chroma:document
string_value:
following declaration for a custom memory resource fulfills the requirements (of course, you would still need to implement the declared functions in this class):classCustomMemoryResource:publicstd::pmr::memory_resource{private:void*do_allocate(std::size_tbytes,std::size_talignment)override;voiddo_deallocate(void*p,std::size_tbytes,std::size_talignment)override;booldo_is_equal(conststd::pmr::memory_resource&other)constnoexceptoverride;};To learn about the full capabilities ofstd::pmr::memory_resource, seehttps://en.cppreference.com/w/cpp/memory/memory_resource.The full implementation of the custom allocator for this tutorial is inhttps://github.com/ros2/demos/blob/jazzy/demo_nodes_cpp/src/topics/allocator_tutorial_pmr.cpp.Writing an example mainOnce you have written a valid C++ allocator, you must pass it as a shared pointer to your publisher, subscriber, and executor. But first, we’ll declare a few aliases to shorten the


