Merge branch 'tracetools' into 'master'
See merge request micro-ROS/ros2_tracing!1 Signed-off-by: Ingo Luetkebohle <ingo.luetkebohle@de.bosch.com>
This commit is contained in:
		
						commit
						cc3c142f9f
					
				
					 37 changed files with 2981 additions and 0 deletions
				
			
		
							
								
								
									
										32
									
								
								.gitlab-ci.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.gitlab-ci.yml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					image: ros:dashing-ros-base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variables:
 | 
				
			||||||
 | 
					  DOCKER_DRIVER: overlay2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					before_script:
 | 
				
			||||||
 | 
					  - apt update
 | 
				
			||||||
 | 
					  - rosdep update
 | 
				
			||||||
 | 
					  - rosdep install -y --from-paths . -i .
 | 
				
			||||||
 | 
					  - ln -s src
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					build:
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - colcon build
 | 
				
			||||||
 | 
					    - colcon test
 | 
				
			||||||
 | 
					  artifacts:
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					      - install
 | 
				
			||||||
 | 
					      - build
 | 
				
			||||||
 | 
					    reports:
 | 
				
			||||||
 | 
					      junit: build/**/Test.xml
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					build_enabled:
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - colcon build --cmake-args -DWITH_LTTNG=ON
 | 
				
			||||||
 | 
					    - colcon test
 | 
				
			||||||
 | 
					  artifacts:
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					      - install
 | 
				
			||||||
 | 
					      - build
 | 
				
			||||||
 | 
					    reports:
 | 
				
			||||||
 | 
					      junit: build/**/Test.xml
 | 
				
			||||||
							
								
								
									
										202
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,202 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                 Apache License
 | 
				
			||||||
 | 
					                           Version 2.0, January 2004
 | 
				
			||||||
 | 
					                        http://www.apache.org/licenses/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   1. Definitions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "License" shall mean the terms and conditions for use, reproduction,
 | 
				
			||||||
 | 
					      and distribution as defined by Sections 1 through 9 of this document.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Licensor" shall mean the copyright owner or entity authorized by
 | 
				
			||||||
 | 
					      the copyright owner that is granting the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Legal Entity" shall mean the union of the acting entity and all
 | 
				
			||||||
 | 
					      other entities that control, are controlled by, or are under common
 | 
				
			||||||
 | 
					      control with that entity. For the purposes of this definition,
 | 
				
			||||||
 | 
					      "control" means (i) the power, direct or indirect, to cause the
 | 
				
			||||||
 | 
					      direction or management of such entity, whether by contract or
 | 
				
			||||||
 | 
					      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
				
			||||||
 | 
					      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "You" (or "Your") shall mean an individual or Legal Entity
 | 
				
			||||||
 | 
					      exercising permissions granted by this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Source" form shall mean the preferred form for making modifications,
 | 
				
			||||||
 | 
					      including but not limited to software source code, documentation
 | 
				
			||||||
 | 
					      source, and configuration files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Object" form shall mean any form resulting from mechanical
 | 
				
			||||||
 | 
					      transformation or translation of a Source form, including but
 | 
				
			||||||
 | 
					      not limited to compiled object code, generated documentation,
 | 
				
			||||||
 | 
					      and conversions to other media types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Work" shall mean the work of authorship, whether in Source or
 | 
				
			||||||
 | 
					      Object form, made available under the License, as indicated by a
 | 
				
			||||||
 | 
					      copyright notice that is included in or attached to the work
 | 
				
			||||||
 | 
					      (an example is provided in the Appendix below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Derivative Works" shall mean any work, whether in Source or Object
 | 
				
			||||||
 | 
					      form, that is based on (or derived from) the Work and for which the
 | 
				
			||||||
 | 
					      editorial revisions, annotations, elaborations, or other modifications
 | 
				
			||||||
 | 
					      represent, as a whole, an original work of authorship. For the purposes
 | 
				
			||||||
 | 
					      of this License, Derivative Works shall not include works that remain
 | 
				
			||||||
 | 
					      separable from, or merely link (or bind by name) to the interfaces of,
 | 
				
			||||||
 | 
					      the Work and Derivative Works thereof.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contribution" shall mean any work of authorship, including
 | 
				
			||||||
 | 
					      the original version of the Work and any modifications or additions
 | 
				
			||||||
 | 
					      to that Work or Derivative Works thereof, that is intentionally
 | 
				
			||||||
 | 
					      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
				
			||||||
 | 
					      or by an individual or Legal Entity authorized to submit on behalf of
 | 
				
			||||||
 | 
					      the copyright owner. For the purposes of this definition, "submitted"
 | 
				
			||||||
 | 
					      means any form of electronic, verbal, or written communication sent
 | 
				
			||||||
 | 
					      to the Licensor or its representatives, including but not limited to
 | 
				
			||||||
 | 
					      communication on electronic mailing lists, source code control systems,
 | 
				
			||||||
 | 
					      and issue tracking systems that are managed by, or on behalf of, the
 | 
				
			||||||
 | 
					      Licensor for the purpose of discussing and improving the Work, but
 | 
				
			||||||
 | 
					      excluding communication that is conspicuously marked or otherwise
 | 
				
			||||||
 | 
					      designated in writing by the copyright owner as "Not a Contribution."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
				
			||||||
 | 
					      on behalf of whom a Contribution has been received by Licensor and
 | 
				
			||||||
 | 
					      subsequently incorporated within the Work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      copyright license to reproduce, prepare Derivative Works of,
 | 
				
			||||||
 | 
					      publicly display, publicly perform, sublicense, and distribute the
 | 
				
			||||||
 | 
					      Work and such Derivative Works in Source or Object form.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   3. Grant of Patent License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      (except as stated in this section) patent license to make, have made,
 | 
				
			||||||
 | 
					      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
				
			||||||
 | 
					      where such license applies only to those patent claims licensable
 | 
				
			||||||
 | 
					      by such Contributor that are necessarily infringed by their
 | 
				
			||||||
 | 
					      Contribution(s) alone or by combination of their Contribution(s)
 | 
				
			||||||
 | 
					      with the Work to which such Contribution(s) was submitted. If You
 | 
				
			||||||
 | 
					      institute patent litigation against any entity (including a
 | 
				
			||||||
 | 
					      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
				
			||||||
 | 
					      or a Contribution incorporated within the Work constitutes direct
 | 
				
			||||||
 | 
					      or contributory patent infringement, then any patent licenses
 | 
				
			||||||
 | 
					      granted to You under this License for that Work shall terminate
 | 
				
			||||||
 | 
					      as of the date such litigation is filed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   4. Redistribution. You may reproduce and distribute copies of the
 | 
				
			||||||
 | 
					      Work or Derivative Works thereof in any medium, with or without
 | 
				
			||||||
 | 
					      modifications, and in Source or Object form, provided that You
 | 
				
			||||||
 | 
					      meet the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (a) You must give any other recipients of the Work or
 | 
				
			||||||
 | 
					          Derivative Works a copy of this License; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (b) You must cause any modified files to carry prominent notices
 | 
				
			||||||
 | 
					          stating that You changed the files; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (c) You must retain, in the Source form of any Derivative Works
 | 
				
			||||||
 | 
					          that You distribute, all copyright, patent, trademark, and
 | 
				
			||||||
 | 
					          attribution notices from the Source form of the Work,
 | 
				
			||||||
 | 
					          excluding those notices that do not pertain to any part of
 | 
				
			||||||
 | 
					          the Derivative Works; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (d) If the Work includes a "NOTICE" text file as part of its
 | 
				
			||||||
 | 
					          distribution, then any Derivative Works that You distribute must
 | 
				
			||||||
 | 
					          include a readable copy of the attribution notices contained
 | 
				
			||||||
 | 
					          within such NOTICE file, excluding those notices that do not
 | 
				
			||||||
 | 
					          pertain to any part of the Derivative Works, in at least one
 | 
				
			||||||
 | 
					          of the following places: within a NOTICE text file distributed
 | 
				
			||||||
 | 
					          as part of the Derivative Works; within the Source form or
 | 
				
			||||||
 | 
					          documentation, if provided along with the Derivative Works; or,
 | 
				
			||||||
 | 
					          within a display generated by the Derivative Works, if and
 | 
				
			||||||
 | 
					          wherever such third-party notices normally appear. The contents
 | 
				
			||||||
 | 
					          of the NOTICE file are for informational purposes only and
 | 
				
			||||||
 | 
					          do not modify the License. You may add Your own attribution
 | 
				
			||||||
 | 
					          notices within Derivative Works that You distribute, alongside
 | 
				
			||||||
 | 
					          or as an addendum to the NOTICE text from the Work, provided
 | 
				
			||||||
 | 
					          that such additional attribution notices cannot be construed
 | 
				
			||||||
 | 
					          as modifying the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      You may add Your own copyright statement to Your modifications and
 | 
				
			||||||
 | 
					      may provide additional or different license terms and conditions
 | 
				
			||||||
 | 
					      for use, reproduction, or distribution of Your modifications, or
 | 
				
			||||||
 | 
					      for any such Derivative Works as a whole, provided Your use,
 | 
				
			||||||
 | 
					      reproduction, and distribution of the Work otherwise complies with
 | 
				
			||||||
 | 
					      the conditions stated in this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
				
			||||||
 | 
					      any Contribution intentionally submitted for inclusion in the Work
 | 
				
			||||||
 | 
					      by You to the Licensor shall be under the terms and conditions of
 | 
				
			||||||
 | 
					      this License, without any additional terms or conditions.
 | 
				
			||||||
 | 
					      Notwithstanding the above, nothing herein shall supersede or modify
 | 
				
			||||||
 | 
					      the terms of any separate license agreement you may have executed
 | 
				
			||||||
 | 
					      with Licensor regarding such Contributions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   6. Trademarks. This License does not grant permission to use the trade
 | 
				
			||||||
 | 
					      names, trademarks, service marks, or product names of the Licensor,
 | 
				
			||||||
 | 
					      except as required for reasonable and customary use in describing the
 | 
				
			||||||
 | 
					      origin of the Work and reproducing the content of the NOTICE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
				
			||||||
 | 
					      agreed to in writing, Licensor provides the Work (and each
 | 
				
			||||||
 | 
					      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
				
			||||||
 | 
					      implied, including, without limitation, any warranties or conditions
 | 
				
			||||||
 | 
					      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
				
			||||||
 | 
					      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
				
			||||||
 | 
					      appropriateness of using or redistributing the Work and assume any
 | 
				
			||||||
 | 
					      risks associated with Your exercise of permissions under this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   8. Limitation of Liability. In no event and under no legal theory,
 | 
				
			||||||
 | 
					      whether in tort (including negligence), contract, or otherwise,
 | 
				
			||||||
 | 
					      unless required by applicable law (such as deliberate and grossly
 | 
				
			||||||
 | 
					      negligent acts) or agreed to in writing, shall any Contributor be
 | 
				
			||||||
 | 
					      liable to You for damages, including any direct, indirect, special,
 | 
				
			||||||
 | 
					      incidental, or consequential damages of any character arising as a
 | 
				
			||||||
 | 
					      result of this License or out of the use or inability to use the
 | 
				
			||||||
 | 
					      Work (including but not limited to damages for loss of goodwill,
 | 
				
			||||||
 | 
					      work stoppage, computer failure or malfunction, or any and all
 | 
				
			||||||
 | 
					      other commercial damages or losses), even if such Contributor
 | 
				
			||||||
 | 
					      has been advised of the possibility of such damages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   9. Accepting Warranty or Additional Liability. While redistributing
 | 
				
			||||||
 | 
					      the Work or Derivative Works thereof, You may choose to offer,
 | 
				
			||||||
 | 
					      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
				
			||||||
 | 
					      or other liability obligations and/or rights consistent with this
 | 
				
			||||||
 | 
					      License. However, in accepting such obligations, You may act only
 | 
				
			||||||
 | 
					      on Your own behalf and on Your sole responsibility, not on behalf
 | 
				
			||||||
 | 
					      of any other Contributor, and only if You agree to indemnify,
 | 
				
			||||||
 | 
					      defend, and hold each Contributor harmless for any liability
 | 
				
			||||||
 | 
					      incurred by, or claims asserted against, such Contributor by reason
 | 
				
			||||||
 | 
					      of your accepting any such warranty or additional liability.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   APPENDIX: How to apply the Apache License to your work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      To apply the Apache License to your work, attach the following
 | 
				
			||||||
 | 
					      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
				
			||||||
 | 
					      replaced with your own identifying information. (Don't include
 | 
				
			||||||
 | 
					      the brackets!)  The text should be enclosed in the appropriate
 | 
				
			||||||
 | 
					      comment syntax for the file format. We also recommend that a
 | 
				
			||||||
 | 
					      file or class name and description of purpose be included on the
 | 
				
			||||||
 | 
					      same "printed page" as the copyright notice for easier
 | 
				
			||||||
 | 
					      identification within third-party archives.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Copyright [yyyy] [name of copyright owner]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
							
								
								
									
										518
									
								
								doc/design_ros_2.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										518
									
								
								doc/design_ros_2.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,518 @@
 | 
				
			||||||
 | 
					# ROS 2 tracing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Design document for ROS 2 tracing, instrumentation, and analysis effort.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Introduction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tracing allows to record run-time data from a system, both for system data (e.g., when a process
 | 
				
			||||||
 | 
					is being scheduled, or when I/O occurs) and for user-defined data. This package helps with
 | 
				
			||||||
 | 
					user-defined trace data within the ROS2 framework, e.g. to trace when messages arrive,
 | 
				
			||||||
 | 
					when timers fire, when callbacks are being run, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Goals and requirements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Goals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Provide low-overhead tools and resources for robotics software development based on ROS 2.
 | 
				
			||||||
 | 
					2. Make tracing easier to use with ROS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Requirements: instrumentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Instrumentation should be built around the main uses of ROS 2, and should include relevant information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Overall
 | 
				
			||||||
 | 
					    1. When creating a publisher/subscriber/service/client/etc., appropriate references should be kept in order to correlate with other tracepoints related to the same instance.
 | 
				
			||||||
 | 
					1. Publishers & subscriptions
 | 
				
			||||||
 | 
					    1. When creating a publisher/subscription, the effective topic name should be included (i.e. including namespace and after remapping).
 | 
				
			||||||
 | 
					    2. When publishing a message, some sort of message identifier should be included in the tracepoint so it can be tracked through DDS up to the subscriber's side.
 | 
				
			||||||
 | 
					3. Callbacks (subscription, service, client, timer)
 | 
				
			||||||
 | 
					    1. Callback function symbol should be included, whenever possible.
 | 
				
			||||||
 | 
					    2. Information about callback execution (e.g. start & end) should be available.
 | 
				
			||||||
 | 
					4. Timers
 | 
				
			||||||
 | 
					    1. Information about the period should be available.
 | 
				
			||||||
 | 
					5. Executors
 | 
				
			||||||
 | 
					    1. Information about spin cycles & periods should be available.
 | 
				
			||||||
 | 
					6. Others
 | 
				
			||||||
 | 
					    1. Provide generic tracepoints for user code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Requirements: analysis & visualization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Analyses process trace data. They should be general enough to be useful for different use-cases, e.g.:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Callback duration
 | 
				
			||||||
 | 
					* Time between callbacks (between two callback starts and/or a callback end and a start)
 | 
				
			||||||
 | 
					* Message age (as the difference between processing time and message timestamp)
 | 
				
			||||||
 | 
					* Message size
 | 
				
			||||||
 | 
					* Memory usage
 | 
				
			||||||
 | 
					* Execution time/proportion accross a process' nodes/components
 | 
				
			||||||
 | 
					* Interruptions (noting that these may be more useful as time-based metrics instead of overall statistics):
 | 
				
			||||||
 | 
					    * scheduling events during a callback
 | 
				
			||||||
 | 
					    * delay between the moment a thread becomes ready and when it's actually scheduled
 | 
				
			||||||
 | 
					    * CPU cycles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with mean, stdev, etc. when applicable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Generic tracepoints for ROS 2 user code could be applied to a user-provided model for higher-level behaviour statistics and visualization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Tools/accessibility
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To make tracing ROS 2 more accessible and easier to adopt, we can put effort into integrating LTTng session setup & recording into the ROS 2 launch system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This might include converting existing `tracetools` scripts to more flexible Python scripts, and then plugging that into the launch system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Instrumentation design
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This section includes information about ROS 2's design & architecture through descriptions of the main execution flows. The instrumentation can then be built around that.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Flow description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Process creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the call to `rclcpp::init()`, a process-specific `rclcpp::Context` object is fetched and CLI arguments are parsed. Much of the work is actually done by `rcl` through a call to `rcl_init()`. This call processes the `rcl_context_t` handle, which is wrapped by the `Context` object. Also, inside this call, `rcl` calls `rmw_init()` to process the `rmw` context (`rmw_context_t`) as well. This `rmw` handle is itself part of the `rcl_context_t` handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This has to be done once per process, and usually at the very beginning. The components that are then instanciated share this context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant process
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant Context
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process->>rclcpp: rclcpp::init(argc, argv)
 | 
				
			||||||
 | 
					    Note over rclcpp: fetches process-specific Context object
 | 
				
			||||||
 | 
					    rclcpp->>Context: init(argc, argv)
 | 
				
			||||||
 | 
					    Note over Context: allocates rcl_context_t handle
 | 
				
			||||||
 | 
					    Context->>rcl: rcl_init(out rcl_context_t)
 | 
				
			||||||
 | 
					    Note over rcl: validates & processes rcl_context_t handle
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_init(out rmw_context_t)
 | 
				
			||||||
 | 
					    Note over rmw: validates & processes rmw_context_t handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_init, rcl_context_t *)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Node/component creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In ROS 2, a process can contain multiple nodes. These are sometimes referred to as "components."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These components are instanciated by the containing process. They are usually classes that extend `rclcpp::Node`, so that the node initialization work is done by the parent constructor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This parent constructor will allocate its own `rcl_node_t` handle and call `rcl_node_init()`, which will validate the node name/namespace. `rcl` will also call `rmw_create_node()` to get the node's `rmw` handle (`rmw_node_t`). This will be used later by publishers and subscriptions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant process
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process->>Component: Component()
 | 
				
			||||||
 | 
					    Component->>rclcpp: : Node(node_name, namespace)
 | 
				
			||||||
 | 
					    Note over rclcpp: allocates rcl_node_t handle
 | 
				
			||||||
 | 
					    rclcpp->>rcl: rcl_node_init(out rcl_node_t, node_name, namespace)
 | 
				
			||||||
 | 
					    Note over rcl: validates node name/namespace
 | 
				
			||||||
 | 
					    Note over rcl: populates rcl_note_t
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_create_node(node_name, local_namespace) : rmw_node_t
 | 
				
			||||||
 | 
					    Note over rmw: creates rmw_node_t handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_node_init, rcl_node_t *, rmw_node_t *, node_name, namespace)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Publisher creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The component calls `create_publisher()`, a `rclcpp::Node` method for convenience. That ends up creating an `rclcpp::Publisher` object which extends `rclcpp::PublisherBase`. The latter allocates an `rcl_publisher_t` handle, fetches the corresponding `rcl_node_t` handle, and calls `rcl_publisher_init()` in its constructor. `rcl` does topic name expansion/remapping/validation. It creates an `rmw_publisher_t` handle by calling `rmw_create_publisher()` of the given `rmw` implementation and associates with the node's `rmw_node_t` handle and the publisher's `rcl_publisher_t` handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If intra-process publishing/subscription is enabled, it will be set up after creating the publisher object, through a call to `PublisherBase::setup_intra_process()`, which calls `rcl_publisher_init()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant Publisher
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>rclcpp: create_publisher(topic_name, options, use_intra_process)
 | 
				
			||||||
 | 
					    Note over rclcpp: (...)
 | 
				
			||||||
 | 
					    rclcpp->>Publisher: Publisher(topic_name, options)
 | 
				
			||||||
 | 
					    Note over Publisher: allocates rcl_publisher_t handle
 | 
				
			||||||
 | 
					    Publisher->>rcl: rcl_publisher_init(out rcl_publisher_t, rcl_node_t, topic_name, options)
 | 
				
			||||||
 | 
					    Note over rcl: populates rcl_publisher_t
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_create_publisher(rmw_node_t, topic_name, qos_options) : rmw_publisher_t
 | 
				
			||||||
 | 
					    Note over rmw: creates rmw_publisher_t handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_publisher_init, rcl_node_t *, rcl_publisher_t *, rmw_publisher_t *, topic_name, depth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    opt use_intra_process
 | 
				
			||||||
 | 
					        rclcpp->>Publisher: setup_intra_process()
 | 
				
			||||||
 | 
					        Publisher->>rcl: rcl_publisher_init(...)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Subscription creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Subscription creation is done in a very similar manner.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The componenent calls `create_publisher()`, which ends up creating an `rclcpp::Subscription` object which extends `rclcpp::SubscriptionBase`. The latter allocates an `rcl_subscription_t` handle, fetches its `rcl_node_t` handle, and calls `rcl_subscription_init()` in its constructor. `rcl` does topic name expansion/remapping/validation. It creates an `rmw_subscription_t` handle by calling `rmw_create_subscription()` of the given `rmw` implementation and associates it with the node's `rmw_node_t` handle and the subscription's `rcl_subscription_t` handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If intra-process publishing/subscription is enabled, it will be set up after creating the subscription object, through a call to `Subscription::setup_intra_process()`, which calls `rcl_subscription_init()`. This is very similar to a normal (inter-process) subscription, but it sets some flags for later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant Subscription
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>rclcpp: create_subscription(topic_name, callback, options, use_intra_process)
 | 
				
			||||||
 | 
					    Note over rclcpp: (...)
 | 
				
			||||||
 | 
					    rclcpp->>Subscription: Subscription(topic_name, callback, options)
 | 
				
			||||||
 | 
					    Note over Subscription: allocates rcl_subscription_t handle
 | 
				
			||||||
 | 
					    Subscription->>rcl: rcl_subscription_init(out rcl_subscription_t, rcl_node_t, topic_name, options)
 | 
				
			||||||
 | 
					    Note over rcl: populates rcl_subscription_t
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_create_subscription(rmw_node_t, topic_name, qos_options) : rmw_subscription_t
 | 
				
			||||||
 | 
					    Note over rmw: creates rmw_subscription_t handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_subscription_init, rcl_node_t *, rcl_subscription_t *, rmw_subscription_t *, topic_name, depth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    opt use_intra_process
 | 
				
			||||||
 | 
					        rclcpp->>Subscription: setup_intra_process()
 | 
				
			||||||
 | 
					        Subscription->>rcl: rcl_subscription_init(...)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rclcpp-->>tracetools: TP(rclcpp_subscription_callback_added, rcl_subscription_t *, &any_callback)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Executors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An `rclcpp::executor::Executor` object is created for a given process. It can be a `SingleThreadedExecutor` or a `MultiThreadedExecutor`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Components are instanciated, usually as a `shared_ptr` through `std::make_shared<Component>()`, then added to the executor with `Executor::add_node()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After all the components have been added, `Executor::spin()` is called. `SingleThreadedExecutor::spin()` simply loops forever until the process' context isn't valid anymore. It fetches the next `rclcpp::AnyExecutable` (e.g. subscription, timer, service, client), and calls `Executor::execute_any_executable()` with it. This then calls the relevant `execute*()` method (e.g. `execute_timer()`, `execute_subscription()`, `execute_intra_process_subscription()`, `execute_service()`, `execute_client()`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant process
 | 
				
			||||||
 | 
					    participant Executor
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process->>Executor: Executor()
 | 
				
			||||||
 | 
					    Note over process: instanciates components
 | 
				
			||||||
 | 
					    process->>Executor: add_node(component)
 | 
				
			||||||
 | 
					    process->>Executor: spin()
 | 
				
			||||||
 | 
					    loop until shutdown
 | 
				
			||||||
 | 
					        Executor-->>tracetools: TP(?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Note over Executor: get_next_executable()
 | 
				
			||||||
 | 
					        Note over Executor: execute_any_executable()
 | 
				
			||||||
 | 
					        Note over Executor: execute_*()
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Subscription callbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Subscriptions are handled in the `rclcpp` layer. Callbacks are wrapped by an `rclcpp::AnySubscriptionCallback` object, which is registered when creating the `rclcpp::Subscription` object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In `execute_*subscription()`, the `Executor` asks the `Subscription` to allocate a message though `Subscription::create_message()`. It then calls `rcl_take*()`, which calls `rmw_take_with_info()`. If that is successful, the `Executor` then passes that on to the subscription through `rclcpp::SubscriptionBase::handle_message()`. This checks if it's the right type of subscription (i.e. inter vs. intra process), then it calls `dispatch()` on the `rclcpp::AnySubscriptionCallback` object with the message (cast to the actual type). This calls the actual `std::function` with the right signature.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally, it returns the message object through `Subscription::return_message()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Executor
 | 
				
			||||||
 | 
					    participant Subscription
 | 
				
			||||||
 | 
					    participant AnySubscriptionCallback
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Executor: execute_subscription()
 | 
				
			||||||
 | 
					    Executor->>Subscription: create_message(): std::shared_ptr<void>
 | 
				
			||||||
 | 
					    Executor->>rcl: rcl_take*(rcl_subscription_t, out msg) : ret
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_take_with_info(rmw_subscription_t, out msg, out taken)
 | 
				
			||||||
 | 
					    Note over rmw: copies available message to msg if there is one
 | 
				
			||||||
 | 
					    opt RCL_RET_OK == ret
 | 
				
			||||||
 | 
					        Executor->>Subscription: handle_message(msg)
 | 
				
			||||||
 | 
					        Note over Subscription: casts msg to its actual type
 | 
				
			||||||
 | 
					        Subscription->>AnySubscriptionCallback: dispatch(typed_msg)
 | 
				
			||||||
 | 
					        AnySubscriptionCallback-->>tracetools: TP(callback_start, this, is_intra_process)
 | 
				
			||||||
 | 
					        Note over AnySubscriptionCallback: std::function(...)
 | 
				
			||||||
 | 
					        AnySubscriptionCallback-->>tracetools: TP(callback_end, this)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    Executor->>Subscription: return_message(msg)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Message publishing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To publish a message, an object is first allocated and then populated by the `Component` (or equivalent). Then, the message is sent to the `Publisher` through `publish()`. This then passes that on to `rcl`, which itself passes it to `rmw`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO add inter- vs. intra-process execution flow
 | 
				
			||||||
 | 
					TODO talk about IntraProcessManager stuff?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant Publisher
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Component: creates a msg
 | 
				
			||||||
 | 
					    Component->>Publisher: publish(msg)
 | 
				
			||||||
 | 
					    Note over Publisher: ...
 | 
				
			||||||
 | 
					    Publisher->>rcl: rcl_publish(rcl_publisher_t, msg)
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_publish(rmw_publisher_t, msg)
 | 
				
			||||||
 | 
					    rmw-->>tracetools: TP(?)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Service creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Service server creation is similar to subscription creation. The `Component` calls `create_service()` which ends up creating a `rclcpp::Service`. In its constructor, it allocates a `rcl_service_t` handle, then calls `rcl_service_init()`. This processes the handle and validates the service name. It calls `rmw_create_service()` to get the corresponding `rmw_service_t` handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant Service
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>rclcpp: create_service(service_name, callback)
 | 
				
			||||||
 | 
					    Note over rclcpp: (...)
 | 
				
			||||||
 | 
					    rclcpp->>Service: Service(rcl_node_t, service_name, callback, options)
 | 
				
			||||||
 | 
					    Note over Service: allocates a rcl_service_t handle
 | 
				
			||||||
 | 
					    Service->>rcl: rcl_service_init(out rcl_service_t, rcl_node_t, service_name, options)
 | 
				
			||||||
 | 
					    Note over rcl: validates & processes service handle
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_create_service(rmw_node_t, service_name, qos_options) : rmw_service_t
 | 
				
			||||||
 | 
					    Note over rmw: creates rmw_service_t handle
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_service_init, rcl_node_t *, rcl_service_t *, rmw_service_t *, service_name)
 | 
				
			||||||
 | 
					    Service-->>tracetools: TP(rclcpp_service_callback_added, rcl_service_t *, &any_callback)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Service callbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Service callbacks are similar to subscription callbacks. In `execute_service()`, the `Executor` allocates request header and request objects. It then calls `rcl_take_request()` and passes them along with the service handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`rcl` calls `rmw_take_request()`. If those are successful, then the `Executor` calls `handle_request()` on the `Service`. This casts the request to its actual type, allocates a response object, and calls `dispatch()` on its `AnyServiceCallback` object, which calls the actual `std::function` with the right signature.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the service response, `Service` calls `rcl_send_response()` which calls `rmw_send_response()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Executor
 | 
				
			||||||
 | 
					    participant Service
 | 
				
			||||||
 | 
					    participant AnyServiceCallback
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Executor: execute_service()
 | 
				
			||||||
 | 
					    Note over Executor: allocates request header and request
 | 
				
			||||||
 | 
					    Executor->>rcl: rcl_take_request(rcl_service, out request_header, out request) : ret
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_take_request(rmw_service_t, out request_header, out request, out taken)
 | 
				
			||||||
 | 
					    opt RCL_RET_OK == ret
 | 
				
			||||||
 | 
					        Executor->>Service: handle_request(request_header, request)
 | 
				
			||||||
 | 
					        Note over Service: casts request to its actual type
 | 
				
			||||||
 | 
					        Note over Service: allocates a response object
 | 
				
			||||||
 | 
					        Service->>AnyServiceCallback: dispatch(request_header, typed_request, response)
 | 
				
			||||||
 | 
					        AnyServiceCallback-->>tracetools: TP(callback_start, this)
 | 
				
			||||||
 | 
					        Note over AnyServiceCallback: std::function(...)
 | 
				
			||||||
 | 
					        AnyServiceCallback-->>tracetools: TP(callback_end, this)
 | 
				
			||||||
 | 
					        Service->>rcl: rcl_send_response(rcl_service_t, request_header, response)
 | 
				
			||||||
 | 
					        rcl->>rmw: rmw_send_response(rmw_service_t, request_header, response)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Client creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client creation is similar to publisher creation. The `Component` calls `create_client()` which ends up creating a `rclcpp::Client`. In its constructor, it allocates a `rcl_client_t` handle, then calls `rcl_client_init()`. This validates and processes the handle. It also calls `rmw_create_client()` which creates the `rmw_client_t` handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant Node
 | 
				
			||||||
 | 
					    participant Client
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>Node: create_client(service_name, options)
 | 
				
			||||||
 | 
					    Node->>Client: Client(service_name, options)
 | 
				
			||||||
 | 
					    Note over Client: allocates a rcl_client_t handle
 | 
				
			||||||
 | 
					    Client->>rcl: rcl_client_init(out rcl_client_t, rcl_node_t, service_name, options)
 | 
				
			||||||
 | 
					    Note over rcl: validates and processes rcl_client_t handle
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_create_client(rmw_node_t, service_name, qos_options) : rmw_client_t
 | 
				
			||||||
 | 
					    Note over rmw: creates rmw_client_t handle
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_client_init, rcl_node_t *, rcl_client_t *, rmw_client_t *, service_name)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Client request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A client request has multiple steps. The `Component` (or the owner of the `Client`) first creates a request object. It then calls `Client::async_send_request()` with the request. It can also provide a callback, but it's optional. The `Client` passes that on to `rcl` by calling `rcl_send_request()`. `rcl` generates a sequence number and assigns it to the request, then calls `rmw_send_request()`. Once this is done, the `Client` puts this sequence number in an internal map along with the created promise and future objects, and the callback (which might simply be empty).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At this point, the `Client` could simply let its callback be called. It can also use the future object returned by `async_send_request()`, and call `rclcpp::spin_until_future_complete()`. This waits until the future object is ready, or until timeout, and returns.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If this last call was successful, then the `Component` can get the result and do something with it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant Executor
 | 
				
			||||||
 | 
					    participant Client
 | 
				
			||||||
 | 
					    participant rclcpp
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant rmw
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over rmw: (implementation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Component: creates request
 | 
				
			||||||
 | 
					    Component->>Client: async_send_request(request[, callback]) : result_future
 | 
				
			||||||
 | 
					    Client->>rcl: rcl_send_request(rcl_client_t, request, out sequence_number)
 | 
				
			||||||
 | 
					    Note over rcl: assigns sequence_number
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP?(rcl_send_request, rcl_client_t *, sequence_number)
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_send_request(rmw_client_t, request, sequence_number)
 | 
				
			||||||
 | 
					    Note over Client: puts sequence_number in a map with promise+callback+future
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>rclcpp: spin_until_future_complete(result_future) : result_status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Executor: execute_client()
 | 
				
			||||||
 | 
					    Note over Executor: creates request_header and response objects
 | 
				
			||||||
 | 
					    Executor->>rcl: rcl_take_response(rcl_client_t, out request_header, out response) : ret
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP?()
 | 
				
			||||||
 | 
					    rcl->>rmw: rmw_take_response(rmw_client_t, out request_header, out response, out taken)
 | 
				
			||||||
 | 
					    opt RCL_RET_OK == ret
 | 
				
			||||||
 | 
					        Executor->>Client: handle_response(request_header, response)
 | 
				
			||||||
 | 
					        Note over Client: gets sequence_number from request_header
 | 
				
			||||||
 | 
					        Client-->>tracetools: TP?()
 | 
				
			||||||
 | 
					        Note over Client: gets promise+callback+future from its map
 | 
				
			||||||
 | 
					        Note over Client: callback(future)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rclcpp->>Component: ready or timeout
 | 
				
			||||||
 | 
					    opt SUCCESS == result_status
 | 
				
			||||||
 | 
					        Note over Component: result_future.get() : result
 | 
				
			||||||
 | 
					        Note over Component: do something with result
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Timer creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer creation is similar to subscription creation. The `Component` calls `create_service()` which ends up creating a `rclcpp::WallTimer`. In its constructor, it creates a `rclcpp::Clock` object, which (for a `WallTimer`) is simply a nanosecond clock. It then allocates a `rcl_timer_t` handle, then calls `rcl_timer_init()`. This processes the handle and validates the period.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that `rcl_timer_init()` can take a callback as a parameter, but right now that feature is not used anywhere (`nullptr` is given), and callbacks are instead handled in the `rclcpp` layer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Component
 | 
				
			||||||
 | 
					    participant Node
 | 
				
			||||||
 | 
					    participant WallTimer
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Component->>Node: create_wall_timer(period, callback)
 | 
				
			||||||
 | 
					    Node->>WallTimer: WallTimer(period, callback, Context)
 | 
				
			||||||
 | 
					    Note over WallTimer: creates a Clock object
 | 
				
			||||||
 | 
					    Note over WallTimer: allocates a rcl_timer_t handle
 | 
				
			||||||
 | 
					    WallTimer->>rcl: rcl_timer_init(out rcl_timer_t, Clock, rcl_context_t, period)
 | 
				
			||||||
 | 
					    Note over rcl: validates and processes rcl_timer_t handle
 | 
				
			||||||
 | 
					    rcl-->>tracetools: TP(rcl_timer_init, rcl_timer_t *, period)
 | 
				
			||||||
 | 
					    WallTimer-->>tracetools: TP(rclcpp_timer_callback_added, rcl_timer_t *, &callback)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Timer callbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer callbacks are similar to susbcription callbacks. In `execute_timer()`, the `Executor` calls `execute_callback()` on the `WallTimer`. The timer then calls `rcl_timer_call()` with its `rcl_timer_t` handle and checks if the callback should be called.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If it that is the case, then the timer will call the actual `std::function`. Depending on the `std::function` that was given when creating the timer, it will either call the callback without any parameters or it will pass a reference of itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    participant Executor
 | 
				
			||||||
 | 
					    participant WallTimer
 | 
				
			||||||
 | 
					    participant rcl
 | 
				
			||||||
 | 
					    participant tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note over Executor: execute_timer()
 | 
				
			||||||
 | 
					    Executor->>WallTimer: execute_callback()
 | 
				
			||||||
 | 
					    WallTimer->>rcl: rcl_timer_call(rcl_timer_t) : ret
 | 
				
			||||||
 | 
					    Note over rcl: validates and updates timer
 | 
				
			||||||
 | 
					    opt RCL_RET_TIMER_CANCELED != ret && RCL_RET_OK == ret
 | 
				
			||||||
 | 
					        WallTimer-->>tracetools: TP(callback_start, &callback)
 | 
				
			||||||
 | 
					        Note over WallTimer: std::function(...)
 | 
				
			||||||
 | 
					        WallTimer-->>tracetools: TP(callback_end, &callback)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Design & implementation notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Targeted tools/dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The targeted tools or dependencies are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* LTTng for tracing
 | 
				
			||||||
 | 
					* pandas and Jupyter for analysis & visualization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Design
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The plan is to use LTTng with a ROS wrapper package like `tracetools` for ROS 1. The suggested setup is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* a tracing package (e.g. `tracetools`) wraps calls to LTTng
 | 
				
			||||||
 | 
					* ROS 2 is instrumented with calls to the tracing package, therefore it becomes a dependency and ships with the core stack
 | 
				
			||||||
 | 
					* by default, the tracing package's functions are empty -- they do not do anything
 | 
				
			||||||
 | 
					* if users wants to enable tracing, they need to
 | 
				
			||||||
 | 
					    * install LTTng
 | 
				
			||||||
 | 
					    * compile the tracing package from source, setting the right compile flag(s)
 | 
				
			||||||
 | 
					    * overlay it on top of their ROS 2 installation
 | 
				
			||||||
 | 
					* use other package(s) for analysis and visualization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Architecture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Timeline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The first goal is to statically instrument ROS 2, aiming for it to be in the ROS 2 E-turtle release (Nov 2019).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This includes transposing the existing ROS 1 instrumentation to ROS 2, wherever applicable. This step may not include instrumenting DDS implementations, and thus may be limited to the layer(s) right before `rmw`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Notes on client libraries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ROS offer a client library (`rcl`) written in C as the base for any language-specific implementation, such as `rclcpp` and `rclpy`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, `rcl` is obviously fairly basic, and still does leave a fair amount of implementation work up to the client libraries. For example, callbacks are not handled in `rcl`, and are left to the client library implementations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This means that some instrumentation work will have to be re-done for every client library that we want to trace. We cannot simply instrument `rcl`, nor can we only instrument the base `rmw` interface if we want to dig into that.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This effort should first focus on `rcl` and `rclcpp` , but `rclpy` should eventually be added and supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### ROS 1/2 compatibility
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We could look into making analyses work on both ROS 1 and ROS 2, through a common instrumentation interface (or other abstraction).
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								doc/img/tracing_architecture.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/img/tracing_architecture.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 107 KiB  | 
							
								
								
									
										23
									
								
								doc/public_post_plan.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								doc/public_post_plan.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Plan for a first public post/announcement.
 | 
				
			||||||
 | 
					This week.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Simple example:
 | 
				
			||||||
 | 
					* Jupyter notebook to plot:
 | 
				
			||||||
 | 
					    * subscription callback duration
 | 
				
			||||||
 | 
					    * CPU cycles/callback
 | 
				
			||||||
 | 
					* and resolve/demangle symbols
 | 
				
			||||||
 | 
					* Include all files/scripts needed to get the result, but keep it simple
 | 
				
			||||||
 | 
					* To be hosted somewhere
 | 
				
			||||||
 | 
					* With some documentation/guide on how to try it out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Post:
 | 
				
			||||||
 | 
					* Mention that we're working on this
 | 
				
			||||||
 | 
					* Talk about goals in general
 | 
				
			||||||
 | 
					* Target = next release
 | 
				
			||||||
 | 
					* Show off example
 | 
				
			||||||
 | 
					* Invite people to ask questions/discuss
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Architecture considerations (right now but also later):
 | 
				
			||||||
 | 
					* Try to use a dataframe as a ROS model abstraction, instead of first going through a layer with python data structures
 | 
				
			||||||
 | 
					* 
 | 
				
			||||||
							
								
								
									
										96
									
								
								tracetools/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tracetools/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					project(tracetools)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Default to C++14
 | 
				
			||||||
 | 
					if(NOT CMAKE_CXX_STANDARD)
 | 
				
			||||||
 | 
					  set(CMAKE_CXX_STANDARD 14)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
 | 
				
			||||||
 | 
					  add_compile_options(-Wall -Wextra -Wpedantic -fPIC)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_package(ament_cmake REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					option(WITH_LTTNG "Include support for tracing with LTTng" OFF)
 | 
				
			||||||
 | 
					if(WITH_LTTNG)
 | 
				
			||||||
 | 
					  # Try to find LTTng
 | 
				
			||||||
 | 
					  find_package(PkgConfig REQUIRED)
 | 
				
			||||||
 | 
					  pkg_check_modules(LTTNG REQUIRED lttng-ust)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					if(LTTNG_FOUND)
 | 
				
			||||||
 | 
					  set(LTTNG_TP_FILES
 | 
				
			||||||
 | 
					    include/tracetools/tp_call.h
 | 
				
			||||||
 | 
					    src/tp_call.c
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  set(TRACING_ENABLED TRUE)
 | 
				
			||||||
 | 
					  message("LTTng found: tracing enabled")
 | 
				
			||||||
 | 
					elseif(WITH_LTTNG)
 | 
				
			||||||
 | 
					  message("LTTng NOT found: tracing disabled")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include_directories(include)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Status checking tool
 | 
				
			||||||
 | 
					add_executable(status
 | 
				
			||||||
 | 
					  src/status.c
 | 
				
			||||||
 | 
					  src/tracetools.c
 | 
				
			||||||
 | 
					  src/utils.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					target_link_libraries(status
 | 
				
			||||||
 | 
					  ${PROJECT_NAME}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					ament_target_dependencies(status
 | 
				
			||||||
 | 
					  ${PROJECT_NAME}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					install(TARGETS
 | 
				
			||||||
 | 
					  status
 | 
				
			||||||
 | 
					  DESTINATION lib/${PROJECT_NAME}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Tracetools lib
 | 
				
			||||||
 | 
					set(SOURCES
 | 
				
			||||||
 | 
					  src/tracetools.c
 | 
				
			||||||
 | 
					  src/utils.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					if(TRACING_ENABLED)
 | 
				
			||||||
 | 
					  list(APPEND SOURCES ${LTTNG_TP_FILES})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_library(${PROJECT_NAME} ${SOURCES})
 | 
				
			||||||
 | 
					if(TRACING_ENABLED)
 | 
				
			||||||
 | 
					  target_compile_definitions(${PROJECT_NAME} PUBLIC TRACETOOLS_LTTNG_ENABLED)
 | 
				
			||||||
 | 
					  target_link_libraries(${PROJECT_NAME} ${LTTNG_LIBRARIES} -ldl)
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					  target_link_libraries(${PROJECT_NAME})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ament_export_interfaces(${PROJECT_NAME}_export HAS_LIBRARY_TARGET)
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
					  DIRECTORY include/
 | 
				
			||||||
 | 
					  DESTINATION include
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
					  TARGETS ${PROJECT_NAME}
 | 
				
			||||||
 | 
					  EXPORT ${PROJECT_NAME}_export
 | 
				
			||||||
 | 
					  LIBRARY DESTINATION lib
 | 
				
			||||||
 | 
					  ARCHIVE DESTINATION lib
 | 
				
			||||||
 | 
					  RUNTIME DESTINATION bin
 | 
				
			||||||
 | 
					  INCLUDES DESTINATION include
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ament_export_include_directories(include)
 | 
				
			||||||
 | 
					if(TRACING_ENABLED)
 | 
				
			||||||
 | 
					  ament_export_libraries(${PROJECT_NAME} ${LTTNG_LIBRARIES})
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					  ament_export_libraries(${PROJECT_NAME})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(BUILD_TESTING)
 | 
				
			||||||
 | 
					  find_package(ament_lint_auto REQUIRED)
 | 
				
			||||||
 | 
					  ament_lint_auto_find_test_dependencies()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ament_package()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_definitions("-D${PROJECT_NAME}_VERSION=\"${${PROJECT_NAME}_VERSION}\"")
 | 
				
			||||||
							
								
								
									
										26
									
								
								tracetools/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tracetools/README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					# tracetools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Building
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If tracing is not enabled when building, or if LTTng is not found, then this package will not do anything.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To enable tracing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Install [LTTng](https://lttng.org/docs/v2.10/#doc-ubuntu):
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					    $ sudo apt-get install lttng-tools lttng-modules-dkms liblttng-ust-dev
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					2. Build with the `WITH_LTTNG` flag:
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					    $ colcon build --cmake-args " -DWITH_LTTNG=ON"
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					3. Check if tracing is enabled (after sourcing):
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					    $ ros2 run tracetools tracetools_status
 | 
				
			||||||
 | 
					    ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Tracing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					By default, the steps above will not lead to trace data being generated, and thus they will have no impact on execution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LTTng has to be enabled: TODO mention scripts
 | 
				
			||||||
							
								
								
									
										228
									
								
								tracetools/include/tracetools/tp_call.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								tracetools/include/tracetools/tp_call.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,228 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Provide fake header guard for cpplint
 | 
				
			||||||
 | 
					#undef TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
 | 
					#ifndef TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
 | 
					#define TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef TRACEPOINT_PROVIDER
 | 
				
			||||||
 | 
					#define TRACEPOINT_PROVIDER ros2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef TRACEPOINT_INCLUDE
 | 
				
			||||||
 | 
					#define TRACEPOINT_INCLUDE "tracetools/tp_call.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(_TRACETOOLS__TP_CALL_H_) || defined(TRACEPOINT_HEADER_MULTI_READ)
 | 
				
			||||||
 | 
					#define _TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <lttng/tracepoint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, context_handle_arg,
 | 
				
			||||||
 | 
					    const char *, version_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, context_handle, context_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(version, version_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_node_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, node_handle_arg,
 | 
				
			||||||
 | 
					    const void *, rmw_handle_arg,
 | 
				
			||||||
 | 
					    const char *, node_name_arg,
 | 
				
			||||||
 | 
					    const char *, namespace_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, node_handle, node_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, rmw_handle, rmw_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(node_name, node_name_arg)
 | 
				
			||||||
 | 
					    ctf_string(namespace, namespace_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_publisher_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, publisher_handle_arg,
 | 
				
			||||||
 | 
					    const void *, node_handle_arg,
 | 
				
			||||||
 | 
					    const void *, rmw_publisher_handle_arg,
 | 
				
			||||||
 | 
					    const char *, topic_name_arg,
 | 
				
			||||||
 | 
					    const size_t, queue_depth_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, publisher_handle, publisher_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, node_handle, node_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, rmw_publisher_handle, rmw_publisher_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(topic_name, topic_name_arg)
 | 
				
			||||||
 | 
					    ctf_integer(const size_t, queue_depth, queue_depth_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_subscription_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, subscription_handle_arg,
 | 
				
			||||||
 | 
					    const void *, node_handle_arg,
 | 
				
			||||||
 | 
					    const void *, rmw_subscription_handle_arg,
 | 
				
			||||||
 | 
					    const char *, topic_name_arg,
 | 
				
			||||||
 | 
					    const size_t, queue_depth_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, subscription_handle, subscription_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, node_handle, node_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, rmw_subscription_handle, rmw_subscription_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(topic_name, topic_name_arg)
 | 
				
			||||||
 | 
					    ctf_integer(const size_t, queue_depth, queue_depth_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rclcpp_subscription_callback_added,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, subscription_handle_arg,
 | 
				
			||||||
 | 
					    const void *, callback_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, subscription_handle, subscription_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_service_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, service_handle_arg,
 | 
				
			||||||
 | 
					    const void *, node_handle_arg,
 | 
				
			||||||
 | 
					    const void *, rmw_service_handle_arg,
 | 
				
			||||||
 | 
					    const char *, service_name_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, service_handle, service_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, node_handle, node_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, rmw_service_handle, rmw_service_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(service_name, service_name_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rclcpp_service_callback_added,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, service_handle_arg,
 | 
				
			||||||
 | 
					    const void *, callback_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, service_handle, service_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_client_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, client_handle_arg,
 | 
				
			||||||
 | 
					    const void *, node_handle_arg,
 | 
				
			||||||
 | 
					    const void *, rmw_client_handle_arg,
 | 
				
			||||||
 | 
					    const char *, service_name_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, client_handle, client_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, node_handle, node_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, rmw_client_handle, rmw_client_handle_arg)
 | 
				
			||||||
 | 
					    ctf_string(service_name, service_name_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rcl_timer_init,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, timer_handle_arg,
 | 
				
			||||||
 | 
					    int64_t, period_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, timer_handle, timer_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer(int64_t, period, period_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rclcpp_timer_callback_added,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, timer_handle_arg,
 | 
				
			||||||
 | 
					    const void *, callback_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, timer_handle, timer_handle_arg)
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  rclcpp_callback_register,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, callback_arg,
 | 
				
			||||||
 | 
					    const char *, symbol_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					    ctf_string(symbol, symbol_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  callback_start,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, callback_arg,
 | 
				
			||||||
 | 
					    int, is_intra_process_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					    ctf_integer(int, is_intra_process, is_intra_process_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TRACEPOINT_EVENT(
 | 
				
			||||||
 | 
					  TRACEPOINT_PROVIDER,
 | 
				
			||||||
 | 
					  callback_end,
 | 
				
			||||||
 | 
					  TP_ARGS(
 | 
				
			||||||
 | 
					    const void *, callback_arg
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  TP_FIELDS(
 | 
				
			||||||
 | 
					    ctf_integer_hex(const void *, callback, callback_arg)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // _TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <lttng/tracepoint-event.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // TRACETOOLS__TP_CALL_H_
 | 
				
			||||||
							
								
								
									
										153
									
								
								tracetools/include/tracetools/tracetools.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								tracetools/include/tracetools/tracetools.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,153 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TRACETOOLS__TRACETOOLS_H_
 | 
				
			||||||
 | 
					#define TRACETOOLS__TRACETOOLS_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRACEPOINT(event_name, ...) \
 | 
				
			||||||
 | 
					  (ros_trace_ ## event_name)(__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Report whether tracing is compiled in
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool ros_trace_compile_status();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_init,
 | 
				
			||||||
 | 
					  const void * context_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_node_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_node_init,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_handle,
 | 
				
			||||||
 | 
					  const char * node_name,
 | 
				
			||||||
 | 
					  const char * node_namespace);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_publisher_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_publisher_init,
 | 
				
			||||||
 | 
					  const void * publisher_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_publisher_handle,
 | 
				
			||||||
 | 
					  const char * topic_name,
 | 
				
			||||||
 | 
					  const size_t queue_depth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_subscription_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_subscription_init,
 | 
				
			||||||
 | 
					  const void * subscription_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_subscription_handle,
 | 
				
			||||||
 | 
					  const char * topic_name,
 | 
				
			||||||
 | 
					  const size_t queue_depth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rclcpp_subscription_callback_added
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_subscription_callback_added,
 | 
				
			||||||
 | 
					  const void * subscription_handle,
 | 
				
			||||||
 | 
					  const void * callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_service_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_service_init,
 | 
				
			||||||
 | 
					  const void * service_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_service_handle,
 | 
				
			||||||
 | 
					  const char * service_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rclcpp_service_callback_added
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_service_callback_added,
 | 
				
			||||||
 | 
					  const void * service_handle,
 | 
				
			||||||
 | 
					  const void * callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_client_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_client_init,
 | 
				
			||||||
 | 
					  const void * client_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_client_handle,
 | 
				
			||||||
 | 
					  const char * service_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rcl_timer_init
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_timer_init,
 | 
				
			||||||
 | 
					  const void * timer_handle,
 | 
				
			||||||
 | 
					  int64_t period);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rclcpp_timer_callback_added
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_timer_callback_added,
 | 
				
			||||||
 | 
					  const void * timer_handle,
 | 
				
			||||||
 | 
					  const void * callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: rclcpp_callback_register
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_callback_register,
 | 
				
			||||||
 | 
					  const void * callback,
 | 
				
			||||||
 | 
					  const char * function_symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: callback_start
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  callback_start,
 | 
				
			||||||
 | 
					  const void * callback,
 | 
				
			||||||
 | 
					  const bool is_intra_process);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tp: callback_end
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  callback_end,
 | 
				
			||||||
 | 
					  const void * callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // TRACETOOLS__TRACETOOLS_H_
 | 
				
			||||||
							
								
								
									
										35
									
								
								tracetools/include/tracetools/utils.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tracetools/include/tracetools/utils.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TRACETOOLS__UTILS_HPP_
 | 
				
			||||||
 | 
					#define TRACETOOLS__UTILS_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, typename ... U>
 | 
				
			||||||
 | 
					void * get_address(std::function<T(U...)> f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef T (fnType)(U...);
 | 
				
			||||||
 | 
					  fnType ** fnPointer = f.template target<fnType *>();
 | 
				
			||||||
 | 
					  // Might be a lambda
 | 
				
			||||||
 | 
					  if (fnPointer == nullptr) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return reinterpret_cast<void *>(*fnPointer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * get_symbol(void * funptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // TRACETOOLS__UTILS_HPP_
 | 
				
			||||||
							
								
								
									
										24
									
								
								tracetools/package.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tracetools/package.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
 | 
					<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 | 
				
			||||||
 | 
					<package format="2">
 | 
				
			||||||
 | 
					  <name>tracetools</name>
 | 
				
			||||||
 | 
					  <version>0.0.1</version>
 | 
				
			||||||
 | 
					  <description>ROS 2 wrapper for instrumentation</description>
 | 
				
			||||||
 | 
					  <maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
 | 
				
			||||||
 | 
					  <maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
 | 
				
			||||||
 | 
					  <license>Apache Software License 2.0</license>
 | 
				
			||||||
 | 
					  <author email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</author>
 | 
				
			||||||
 | 
					  <author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <buildtool_depend>ament_cmake</buildtool_depend>
 | 
				
			||||||
 | 
					  <buildtool_depend>pkg-config</buildtool_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <depend>liblttng-ust-dev</depend>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <test_depend>ament_lint_auto</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>ament_lint_common</test_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <export>
 | 
				
			||||||
 | 
					    <build_type>ament_cmake</build_type>
 | 
				
			||||||
 | 
					  </export>
 | 
				
			||||||
 | 
					</package>
 | 
				
			||||||
							
								
								
									
										63
									
								
								tracetools/scripts/setup-lttng.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										63
									
								
								tracetools/scripts/setup-lttng.sh
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# set up ust ros2 events
 | 
				
			||||||
 | 
					for event in \
 | 
				
			||||||
 | 
					  ros2:rcl_init \
 | 
				
			||||||
 | 
					  ros2:rcl_node_init \
 | 
				
			||||||
 | 
					  ros2:rcl_publisher_init \
 | 
				
			||||||
 | 
					  ros2:rcl_subscription_init \
 | 
				
			||||||
 | 
					  ros2:rclcpp_subscription_callback_added \
 | 
				
			||||||
 | 
					  ros2:rcl_service_init \
 | 
				
			||||||
 | 
					  ros2:rclcpp_service_callback_added \
 | 
				
			||||||
 | 
					  ros2:rcl_client_init \
 | 
				
			||||||
 | 
					  ros2:rcl_timer_init \
 | 
				
			||||||
 | 
					  ros2:rclcpp_timer_callback_added \
 | 
				
			||||||
 | 
					  ros2:rclcpp_register_callback \
 | 
				
			||||||
 | 
					  ros2:callback_start \
 | 
				
			||||||
 | 
					  ros2:callback_end
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						lttng enable-event -c ros2 -u $event
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# process context
 | 
				
			||||||
 | 
					lttng add-context -c ros2 -u \
 | 
				
			||||||
 | 
					  -t vpid -t procname \
 | 
				
			||||||
 | 
					  -t vtid -t perf:thread:instructions \
 | 
				
			||||||
 | 
					  -t perf:thread:cycles -t perf:thread:cpu-cycles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#kernel
 | 
				
			||||||
 | 
					lttng enable-channel --kernel kchan --subbuf-size=8M
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# # network
 | 
				
			||||||
 | 
					# for event in net_dev_queue netif_receive_skb net_if_receive_skb
 | 
				
			||||||
 | 
					# do
 | 
				
			||||||
 | 
					#     lttng enable-event --kernel --channel=kchan $event
 | 
				
			||||||
 | 
					# done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# other kernel stuff
 | 
				
			||||||
 | 
					for event in sched_switch sched_waking sched_pi_setprio sched_process_fork sched_process_exit sched_process_free sched_wakeup\
 | 
				
			||||||
 | 
					    irq_softirq_entry irq_softirq_raise irq_softirq_exit irq_handler_entry irq_handler_exit\
 | 
				
			||||||
 | 
					    lttng_statedump_process_state lttng_statedump_start lttng_statedump_end lttng_statedump_network_interface lttng_statedump_block_device\
 | 
				
			||||||
 | 
					    block_rq_complete block_rq_insert block_rq_issue\
 | 
				
			||||||
 | 
					    block_bio_frontmerge sched_migrate sched_migrate_task power_cpu_frequency\
 | 
				
			||||||
 | 
					    net_dev_queue netif_receive_skb net_if_receive_skb\
 | 
				
			||||||
 | 
					    timer_hrtimer_start timer_hrtimer_cancel timer_hrtimer_expire_entry timer_hrtimer_expire_exit
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    lttng enable-event --kernel --channel=kchan $event
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# lttng enable-event -k --syscall --all
 | 
				
			||||||
							
								
								
									
										103
									
								
								tracetools/scripts/trace.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										103
									
								
								tracetools/scripts/trace.sh
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,103 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Helper script for ROS tracing
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					## Call this by providing these arguments:
 | 
				
			||||||
 | 
					##  1. a session name [optional; 'ros2' will be used]
 | 
				
			||||||
 | 
					##  2. a wait time before killing and stopping (in seconds)
 | 
				
			||||||
 | 
					##  3. a roslaunch/rosrun command
 | 
				
			||||||
 | 
					## ex: ./trace.sh 3 roslaunch tracecompass_ros_testcases pub_sub.launch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source ./${BASH_SOURCE%/*}/../../../../install/local_setup.bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Parameters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if no parameters were given, exit with error 
 | 
				
			||||||
 | 
					if [ -z "$1" ] ; then
 | 
				
			||||||
 | 
					    echo "Error: no parameters were given!"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					elif [ "$1" == "-h" ] ; then
 | 
				
			||||||
 | 
					    echo -e "ROS tracing helper script.\n" \
 | 
				
			||||||
 | 
					    "Provide 3 arguments:\n" \
 | 
				
			||||||
 | 
					        "1. the lttng session name [optional; 'ros2' will be used]\n" \
 | 
				
			||||||
 | 
					        "2. the wait time before killing and stopping (in seconds)\n" \
 | 
				
			||||||
 | 
					        "3. the ros2 run command\n" \
 | 
				
			||||||
 | 
					    "Example: ./trace.sh ros-trace 3 ros2 run tracetools tracetools_status"
 | 
				
			||||||
 | 
					    exit 0
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# session name
 | 
				
			||||||
 | 
					session_name="$1"
 | 
				
			||||||
 | 
					case "$session_name" in
 | 
				
			||||||
 | 
					    ''|*[!0-9]*) # not a number: good
 | 
				
			||||||
 | 
					    shift
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					    *) # number: so use a default session name
 | 
				
			||||||
 | 
					    session_name="ros2"
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# wait time (seconds) before killing and stopping
 | 
				
			||||||
 | 
					sleep_time="$1"
 | 
				
			||||||
 | 
					case "$sleep_time" in
 | 
				
			||||||
 | 
					    ''|*[!0-9]*) # not a number: error!
 | 
				
			||||||
 | 
					    echo "Error: not a valid sleep time!"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					    *) # number: good
 | 
				
			||||||
 | 
					    shift
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# command from remaining arguments
 | 
				
			||||||
 | 
					if [ -z "$1" ] ; then
 | 
				
			||||||
 | 
					    echo "Error: no command was given!"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					launch_cmd="$@"
 | 
				
			||||||
 | 
					launch_cmd+=" &"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Trace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# create lttng session (and set output to traces/ directory)
 | 
				
			||||||
 | 
					lttng create $session_name --output=./${BASH_SOURCE%/*}/../traces/$session_name/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# enable events
 | 
				
			||||||
 | 
					./${BASH_SOURCE%/*}/setup-lttng.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# start
 | 
				
			||||||
 | 
					lttng start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# preload UST library
 | 
				
			||||||
 | 
					export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/liblttng-ust-cyg-profile.so
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# launch
 | 
				
			||||||
 | 
					eval "$launch_cmd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# wait a bit and kill
 | 
				
			||||||
 | 
					echo "waiting $sleep_time..."
 | 
				
			||||||
 | 
					sleep $sleep_time
 | 
				
			||||||
 | 
					echo "killing"
 | 
				
			||||||
 | 
					kill $!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# wait again for everything to shutdown
 | 
				
			||||||
 | 
					echo "waiting for shutdown..."
 | 
				
			||||||
 | 
					sleep 2
 | 
				
			||||||
 | 
					echo "stopping"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# stop & destroy
 | 
				
			||||||
 | 
					lttng stop
 | 
				
			||||||
 | 
					lttng destroy
 | 
				
			||||||
							
								
								
									
										28
									
								
								tracetools/src/status.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tracetools/src/status.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "tracetools/tracetools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  printf("Tracing ");
 | 
				
			||||||
 | 
					  if (ros_trace_compile_status()) {
 | 
				
			||||||
 | 
					    printf("enabled\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    printf("disabled\n");
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								tracetools/src/tp_call.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tracetools/src/tp_call.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRACEPOINT_CREATE_PROBES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRACEPOINT_DEFINE
 | 
				
			||||||
 | 
					#include "tracetools/tp_call.h"
 | 
				
			||||||
							
								
								
									
										218
									
								
								tracetools/src/tracetools.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								tracetools/src/tracetools.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,218 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tracetools/tracetools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
 | 
				
			||||||
 | 
					# include "tracetools/tp_call.h"
 | 
				
			||||||
 | 
					# define CONDITIONAL_TP(...) \
 | 
				
			||||||
 | 
					  tracepoint(__VA_ARGS__)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define CONDITIONAL_TP(...)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ros_trace_compile_status()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _WIN32
 | 
				
			||||||
 | 
					# pragma GCC diagnostic push
 | 
				
			||||||
 | 
					# pragma GCC diagnostic ignored "-Wunused-parameter"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_init,
 | 
				
			||||||
 | 
					  const void * context_handle)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_init,
 | 
				
			||||||
 | 
					    context_handle,
 | 
				
			||||||
 | 
					    tracetools_VERSION);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_node_init,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_handle,
 | 
				
			||||||
 | 
					  const char * node_name,
 | 
				
			||||||
 | 
					  const char * node_namespace)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_node_init,
 | 
				
			||||||
 | 
					    node_handle,
 | 
				
			||||||
 | 
					    rmw_handle,
 | 
				
			||||||
 | 
					    node_name,
 | 
				
			||||||
 | 
					    node_namespace);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_publisher_init,
 | 
				
			||||||
 | 
					  const void * publisher_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_publisher_handle,
 | 
				
			||||||
 | 
					  const char * topic_name,
 | 
				
			||||||
 | 
					  const size_t queue_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_publisher_init,
 | 
				
			||||||
 | 
					    publisher_handle,
 | 
				
			||||||
 | 
					    node_handle,
 | 
				
			||||||
 | 
					    rmw_publisher_handle,
 | 
				
			||||||
 | 
					    topic_name,
 | 
				
			||||||
 | 
					    queue_depth);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_subscription_init,
 | 
				
			||||||
 | 
					  const void * subscription_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_subscription_handle,
 | 
				
			||||||
 | 
					  const char * topic_name,
 | 
				
			||||||
 | 
					  const size_t queue_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_subscription_init,
 | 
				
			||||||
 | 
					    subscription_handle,
 | 
				
			||||||
 | 
					    node_handle,
 | 
				
			||||||
 | 
					    rmw_subscription_handle,
 | 
				
			||||||
 | 
					    topic_name,
 | 
				
			||||||
 | 
					    queue_depth);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_subscription_callback_added,
 | 
				
			||||||
 | 
					  const void * subscription_handle,
 | 
				
			||||||
 | 
					  const void * callback)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rclcpp_subscription_callback_added,
 | 
				
			||||||
 | 
					    subscription_handle,
 | 
				
			||||||
 | 
					    callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_service_init,
 | 
				
			||||||
 | 
					  const void * service_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_service_handle,
 | 
				
			||||||
 | 
					  const char * service_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_service_init,
 | 
				
			||||||
 | 
					    service_handle,
 | 
				
			||||||
 | 
					    node_handle,
 | 
				
			||||||
 | 
					    rmw_service_handle,
 | 
				
			||||||
 | 
					    service_name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_service_callback_added,
 | 
				
			||||||
 | 
					  const void * service_handle,
 | 
				
			||||||
 | 
					  const void * callback)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rclcpp_service_callback_added,
 | 
				
			||||||
 | 
					    service_handle,
 | 
				
			||||||
 | 
					    callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_client_init,
 | 
				
			||||||
 | 
					  const void * client_handle,
 | 
				
			||||||
 | 
					  const void * node_handle,
 | 
				
			||||||
 | 
					  const void * rmw_client_handle,
 | 
				
			||||||
 | 
					  const char * service_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_client_init,
 | 
				
			||||||
 | 
					    client_handle,
 | 
				
			||||||
 | 
					    node_handle,
 | 
				
			||||||
 | 
					    rmw_client_handle,
 | 
				
			||||||
 | 
					    service_name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rcl_timer_init,
 | 
				
			||||||
 | 
					  const void * timer_handle,
 | 
				
			||||||
 | 
					  int64_t period)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rcl_timer_init,
 | 
				
			||||||
 | 
					    timer_handle,
 | 
				
			||||||
 | 
					    period);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_timer_callback_added,
 | 
				
			||||||
 | 
					  const void * timer_handle,
 | 
				
			||||||
 | 
					  const void * callback)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rclcpp_timer_callback_added,
 | 
				
			||||||
 | 
					    timer_handle,
 | 
				
			||||||
 | 
					    callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  rclcpp_callback_register,
 | 
				
			||||||
 | 
					  const void * callback,
 | 
				
			||||||
 | 
					  const char * function_symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    rclcpp_callback_register,
 | 
				
			||||||
 | 
					    callback,
 | 
				
			||||||
 | 
					    function_symbol);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  callback_start,
 | 
				
			||||||
 | 
					  const void * callback,
 | 
				
			||||||
 | 
					  const bool is_intra_process)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    callback_start,
 | 
				
			||||||
 | 
					    callback,
 | 
				
			||||||
 | 
					    (is_intra_process ? 1 : 0));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TRACEPOINT(
 | 
				
			||||||
 | 
					  callback_end,
 | 
				
			||||||
 | 
					  const void * callback)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CONDITIONAL_TP(
 | 
				
			||||||
 | 
					    ros2,
 | 
				
			||||||
 | 
					    callback_end,
 | 
				
			||||||
 | 
					    callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _WIN32
 | 
				
			||||||
 | 
					# pragma GCC diagnostic pop
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										45
									
								
								tracetools/src/utils.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								tracetools/src/utils.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					#include <cxxabi.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include "tracetools/utils.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * get_symbol(void * funptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#define SYMBOL_UNKNOWN "UNKNOWN"
 | 
				
			||||||
 | 
					#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
 | 
				
			||||||
 | 
					#define SYMBOL_LAMBDA "[lambda]"
 | 
				
			||||||
 | 
					  if (funptr == 0) {
 | 
				
			||||||
 | 
					    return SYMBOL_LAMBDA;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Dl_info info;
 | 
				
			||||||
 | 
					  if (dladdr(funptr, &info) == 0) {
 | 
				
			||||||
 | 
					    return SYMBOL_UNKNOWN;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char * demangled = nullptr;
 | 
				
			||||||
 | 
					  int status;
 | 
				
			||||||
 | 
					  demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
 | 
				
			||||||
 | 
					  // Use demangled symbol if possible
 | 
				
			||||||
 | 
					  const char * demangled_val = (status == 0 ? demangled : info.dli_sname);
 | 
				
			||||||
 | 
					  return demangled_val != 0 ? demangled_val : SYMBOL_UNKNOWN;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  (void)funptr;
 | 
				
			||||||
 | 
					  return SYMBOL_UNKNOWN;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								tracetools_test/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tracetools_test/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					*~
 | 
				
			||||||
 | 
					*.pyc
 | 
				
			||||||
							
								
								
									
										117
									
								
								tracetools_test/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								tracetools_test/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					project(tracetools_test)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Default to C++14
 | 
				
			||||||
 | 
					if(NOT CMAKE_CXX_STANDARD)
 | 
				
			||||||
 | 
					  set(CMAKE_CXX_STANDARD 14)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
 | 
				
			||||||
 | 
					  add_compile_options(-Wall -Wextra -Wpedantic -fPIC)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_package(ament_cmake REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Tests
 | 
				
			||||||
 | 
					if(BUILD_TESTING)
 | 
				
			||||||
 | 
					  find_package(rclcpp REQUIRED)
 | 
				
			||||||
 | 
					  find_package(std_msgs REQUIRED)
 | 
				
			||||||
 | 
					  find_package(std_srvs REQUIRED)
 | 
				
			||||||
 | 
					  find_package(tracetools REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  add_executable(test_publisher
 | 
				
			||||||
 | 
					    src/test_publisher.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_publisher
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_msgs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_subscription
 | 
				
			||||||
 | 
					    src/test_subscription.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_subscription
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_msgs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_ping
 | 
				
			||||||
 | 
					    src/test_ping.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_ping
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_msgs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_pong
 | 
				
			||||||
 | 
					    src/test_pong.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_pong
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_msgs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_timer
 | 
				
			||||||
 | 
					    src/test_timer.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_timer
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_service
 | 
				
			||||||
 | 
					    src/test_service.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_service
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_srvs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_service_ping
 | 
				
			||||||
 | 
					    src/test_service_ping.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_service_ping
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_srvs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  add_executable(test_service_pong
 | 
				
			||||||
 | 
					    src/test_service_pong.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  ament_target_dependencies(test_service_pong
 | 
				
			||||||
 | 
					    rclcpp
 | 
				
			||||||
 | 
					    std_srvs
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  install(TARGETS
 | 
				
			||||||
 | 
					    test_publisher
 | 
				
			||||||
 | 
					    test_subscription
 | 
				
			||||||
 | 
					    test_ping
 | 
				
			||||||
 | 
					    test_pong
 | 
				
			||||||
 | 
					    test_timer
 | 
				
			||||||
 | 
					    test_service
 | 
				
			||||||
 | 
					    test_service_ping
 | 
				
			||||||
 | 
					    test_service_pong
 | 
				
			||||||
 | 
					    DESTINATION lib/${PROJECT_NAME}
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  find_package(ament_lint_auto REQUIRED)
 | 
				
			||||||
 | 
					  ament_lint_auto_find_test_dependencies()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  find_package(ament_cmake_pytest REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Run each test in its own pytest invocation
 | 
				
			||||||
 | 
					  set(_tracetools_test_pytest_tests
 | 
				
			||||||
 | 
					    test/test_node.py
 | 
				
			||||||
 | 
					    test/test_publisher.py
 | 
				
			||||||
 | 
					    test/test_subscription.py
 | 
				
			||||||
 | 
					    test/test_subscription_callback.py
 | 
				
			||||||
 | 
					    test/test_timer.py
 | 
				
			||||||
 | 
					    test/test_service.py
 | 
				
			||||||
 | 
					    test/test_service_callback.py
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  foreach(_test_path ${_tracetools_test_pytest_tests})
 | 
				
			||||||
 | 
					    get_filename_component(_test_name ${_test_path} NAME_WE)
 | 
				
			||||||
 | 
					    ament_add_pytest_test(${_test_name} ${_test_path}
 | 
				
			||||||
 | 
					      PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}"
 | 
				
			||||||
 | 
					      APPEND_ENV AMENT_PREFIX_PATH=${ament_index_build_path}
 | 
				
			||||||
 | 
					        PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}
 | 
				
			||||||
 | 
					      TIMEOUT 60
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  endforeach()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ament_package()
 | 
				
			||||||
							
								
								
									
										33
									
								
								tracetools_test/package.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tracetools_test/package.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
 | 
					<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 | 
				
			||||||
 | 
					<package format="2">
 | 
				
			||||||
 | 
					  <name>tracetools_test</name>
 | 
				
			||||||
 | 
					  <version>0.0.1</version>
 | 
				
			||||||
 | 
					  <description>Separate test package for tracetools</description>
 | 
				
			||||||
 | 
					  <maintainer email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</maintainer>
 | 
				
			||||||
 | 
					  <maintainer email="ingo.luetkebohle@de.bosch.com">Ingo Luetkebohle</maintainer>
 | 
				
			||||||
 | 
					  <license>Apache Software License 2.0</license>
 | 
				
			||||||
 | 
					  <author email="fixed-term.christophe.bourquebedard@de.bosch.com">Christophe Bedard</author>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <buildtool_depend>ament_cmake</buildtool_depend>
 | 
				
			||||||
 | 
					  <buildtool_depend>pkg-config</buildtool_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <build_depend>rclcpp</build_depend>
 | 
				
			||||||
 | 
					  <build_depend>std_msgs</build_depend>
 | 
				
			||||||
 | 
					  <build_depend>std_srvs</build_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <exec_depend>rclcpp</exec_depend>
 | 
				
			||||||
 | 
					  <exec_depend>std_msgs</exec_depend>
 | 
				
			||||||
 | 
					  <exec_depend>std_srvs</exec_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <test_depend>ament_cmake_pytest</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>ament_lint_auto</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>ament_lint_common</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>launch_ros</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>python3-pytest</test_depend>
 | 
				
			||||||
 | 
					  <test_depend>tracetools</test_depend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <export>
 | 
				
			||||||
 | 
					    <build_type>ament_cmake</build_type>
 | 
				
			||||||
 | 
					  </export>
 | 
				
			||||||
 | 
					</package>
 | 
				
			||||||
							
								
								
									
										74
									
								
								tracetools_test/src/test_ping.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								tracetools_test/src/test_ping.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_msgs/msg/string.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std::chrono_literals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PingNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit PingNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("ping_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sub_ = this->create_subscription<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "pong",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10),
 | 
				
			||||||
 | 
					      std::bind(&PingNode::callback, this, std::placeholders::_1));
 | 
				
			||||||
 | 
					    pub_ = this->create_publisher<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "ping",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10));
 | 
				
			||||||
 | 
					    timer_ = this->create_wall_timer(
 | 
				
			||||||
 | 
					      500ms,
 | 
				
			||||||
 | 
					      std::bind(&PingNode::timer_callback, this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void callback(const std_msgs::msg::String::SharedPtr msg)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    RCLCPP_INFO(this->get_logger(), "[output] %s", msg->data.c_str());
 | 
				
			||||||
 | 
					    rclcpp::shutdown();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void timer_callback()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    auto msg = std::make_shared<std_msgs::msg::String>();
 | 
				
			||||||
 | 
					    msg->data = "some random ping string";
 | 
				
			||||||
 | 
					    pub_->publish(*msg);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
 | 
				
			||||||
 | 
					  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
 | 
				
			||||||
 | 
					  rclcpp::TimerBase::SharedPtr timer_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto ping_node = std::make_shared<PingNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(ping_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning\n");
 | 
				
			||||||
 | 
					  exec.spin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Will actually be called inside the node's callback
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										63
									
								
								tracetools_test/src/test_pong.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								tracetools_test/src/test_pong.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_msgs/msg/string.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PongNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit PongNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("pong_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sub_ = this->create_subscription<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "ping",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10),
 | 
				
			||||||
 | 
					      std::bind(&PongNode::callback, this, std::placeholders::_1));
 | 
				
			||||||
 | 
					    pub_ = this->create_publisher<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "pong",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void callback(const std_msgs::msg::String::SharedPtr msg)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    RCLCPP_INFO(this->get_logger(), "[output] %s", msg->data.c_str());
 | 
				
			||||||
 | 
					    auto next_msg = std::make_shared<std_msgs::msg::String>();
 | 
				
			||||||
 | 
					    next_msg->data = "some random pong string";
 | 
				
			||||||
 | 
					    pub_->publish(*next_msg);
 | 
				
			||||||
 | 
					    rclcpp::shutdown();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
 | 
				
			||||||
 | 
					  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto pong_node = std::make_shared<PongNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(pong_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning\n");
 | 
				
			||||||
 | 
					  exec.spin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Will actually be called inside the node's callback
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								tracetools_test/src/test_publisher.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tracetools_test/src/test_publisher.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_msgs/msg/string.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PubNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit PubNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("pub_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    pub_ = this->create_publisher<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "the_topic",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto pub_node = std::make_shared<PubNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(pub_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning once\n");
 | 
				
			||||||
 | 
					  exec.spin_once();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										64
									
								
								tracetools_test/src/test_service.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								tracetools_test/src/test_service.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_srvs/srv/empty.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ServiceNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit ServiceNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("service_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    srv_ = this->create_service<std_srvs::srv::Empty>(
 | 
				
			||||||
 | 
					      "service",
 | 
				
			||||||
 | 
					      std::bind(
 | 
				
			||||||
 | 
					        &ServiceNode::service_callback,
 | 
				
			||||||
 | 
					        this,
 | 
				
			||||||
 | 
					        std::placeholders::_1,
 | 
				
			||||||
 | 
					        std::placeholders::_2,
 | 
				
			||||||
 | 
					        std::placeholders::_3));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void service_callback(
 | 
				
			||||||
 | 
					    const std::shared_ptr<rmw_request_id_t> request_header,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Request> request,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Response> response)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Nothing
 | 
				
			||||||
 | 
					    (void)request_header;
 | 
				
			||||||
 | 
					    (void)request;
 | 
				
			||||||
 | 
					    (void)response;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Service<std_srvs::srv::Empty>::SharedPtr srv_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto service_node = std::make_shared<ServiceNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(service_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning once\n");
 | 
				
			||||||
 | 
					  exec.spin_once();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										82
									
								
								tracetools_test/src/test_service_ping.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								tracetools_test/src/test_service_ping.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_srvs/srv/empty.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std::chrono_literals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PingNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit PingNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("ping_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    srv_ = this->create_service<std_srvs::srv::Empty>(
 | 
				
			||||||
 | 
					      "pong",
 | 
				
			||||||
 | 
					      std::bind(
 | 
				
			||||||
 | 
					        &PingNode::service_callback,
 | 
				
			||||||
 | 
					        this,
 | 
				
			||||||
 | 
					        std::placeholders::_1,
 | 
				
			||||||
 | 
					        std::placeholders::_2,
 | 
				
			||||||
 | 
					        std::placeholders::_3));
 | 
				
			||||||
 | 
					    client_ = this->create_client<std_srvs::srv::Empty>(
 | 
				
			||||||
 | 
					      "ping");
 | 
				
			||||||
 | 
					    timer_ = this->create_wall_timer(
 | 
				
			||||||
 | 
					      500ms,
 | 
				
			||||||
 | 
					      std::bind(&PingNode::timer_callback, this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void service_callback(
 | 
				
			||||||
 | 
					    const std::shared_ptr<rmw_request_id_t> request_header,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Request> request,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Response> response)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    (void)request_header;
 | 
				
			||||||
 | 
					    (void)request;
 | 
				
			||||||
 | 
					    (void)response;
 | 
				
			||||||
 | 
					    RCLCPP_INFO(this->get_logger(), "got request");
 | 
				
			||||||
 | 
					    rclcpp::shutdown();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void timer_callback()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    auto req = std::make_shared<std_srvs::srv::Empty::Request>();
 | 
				
			||||||
 | 
					    client_->async_send_request(req);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Service<std_srvs::srv::Empty>::SharedPtr srv_;
 | 
				
			||||||
 | 
					  rclcpp::Client<std_srvs::srv::Empty>::SharedPtr client_;
 | 
				
			||||||
 | 
					  rclcpp::TimerBase::SharedPtr timer_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto ping_node = std::make_shared<PingNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(ping_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning\n");
 | 
				
			||||||
 | 
					  exec.spin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Will actually be called inside the node's service callback
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										70
									
								
								tracetools_test/src/test_service_pong.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								tracetools_test/src/test_service_pong.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_srvs/srv/empty.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PongNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit PongNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("pong_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    srv_ = this->create_service<std_srvs::srv::Empty>(
 | 
				
			||||||
 | 
					      "ping",
 | 
				
			||||||
 | 
					      std::bind(
 | 
				
			||||||
 | 
					        &PongNode::service_callback,
 | 
				
			||||||
 | 
					        this,
 | 
				
			||||||
 | 
					        std::placeholders::_1,
 | 
				
			||||||
 | 
					        std::placeholders::_2,
 | 
				
			||||||
 | 
					        std::placeholders::_3));
 | 
				
			||||||
 | 
					    client_ = this->create_client<std_srvs::srv::Empty>("pong");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void service_callback(
 | 
				
			||||||
 | 
					    const std::shared_ptr<rmw_request_id_t> request_header,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Request> request,
 | 
				
			||||||
 | 
					    const std::shared_ptr<std_srvs::srv::Empty::Response> response)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    (void)request_header;
 | 
				
			||||||
 | 
					    (void)request;
 | 
				
			||||||
 | 
					    (void)response;
 | 
				
			||||||
 | 
					    RCLCPP_INFO(this->get_logger(), "got request");
 | 
				
			||||||
 | 
					    auto req = std::make_shared<std_srvs::srv::Empty::Request>();
 | 
				
			||||||
 | 
					    client_->async_send_request(req);
 | 
				
			||||||
 | 
					    rclcpp::shutdown();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Service<std_srvs::srv::Empty>::SharedPtr srv_;
 | 
				
			||||||
 | 
					  rclcpp::Client<std_srvs::srv::Empty>::SharedPtr client_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto pong_node = std::make_shared<PongNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(pong_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning\n");
 | 
				
			||||||
 | 
					  exec.spin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Will actually be called inside the node's service callback
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								tracetools_test/src/test_subscription.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								tracetools_test/src/test_subscription.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					#include "std_msgs/msg/string.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SubNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit SubNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("sub_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    sub_ = this->create_subscription<std_msgs::msg::String>(
 | 
				
			||||||
 | 
					      "the_topic",
 | 
				
			||||||
 | 
					      rclcpp::QoS(10),
 | 
				
			||||||
 | 
					      std::bind(&SubNode::callback, this, std::placeholders::_1));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void callback(const std_msgs::msg::String::SharedPtr msg)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Nothing
 | 
				
			||||||
 | 
					    (void)msg;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto sub_node = std::make_shared<SubNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(sub_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning once\n");
 | 
				
			||||||
 | 
					  exec.spin_once();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								tracetools_test/src/test_timer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								tracetools_test/src/test_timer.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					// Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rclcpp/rclcpp.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std::chrono_literals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TimerNode : public rclcpp::Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  explicit TimerNode(rclcpp::NodeOptions options)
 | 
				
			||||||
 | 
					  : Node("timer_node", options)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    is_done_ = false;
 | 
				
			||||||
 | 
					    timer_ = this->create_wall_timer(
 | 
				
			||||||
 | 
					      1ms,
 | 
				
			||||||
 | 
					      std::bind(&TimerNode::timer_callback, this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  void timer_callback()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (is_done_) {
 | 
				
			||||||
 | 
					      rclcpp::shutdown();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      is_done_ = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::TimerBase::SharedPtr timer_;
 | 
				
			||||||
 | 
					  bool is_done_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char * argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  rclcpp::init(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rclcpp::executors::SingleThreadedExecutor exec;
 | 
				
			||||||
 | 
					  auto timer_node = std::make_shared<TimerNode>(rclcpp::NodeOptions());
 | 
				
			||||||
 | 
					  exec.add_node(timer_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("spinning\n");
 | 
				
			||||||
 | 
					  exec.spin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Will actually be called inside the timer's callback
 | 
				
			||||||
 | 
					  rclcpp::shutdown();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								tracetools_test/test/test_node.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tracetools_test/test/test_node.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					node_creation_events = [
 | 
				
			||||||
 | 
					    'ros2:rcl_init',
 | 
				
			||||||
 | 
					    'ros2:rcl_node_init',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestNode(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_creation(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-node-creation'
 | 
				
			||||||
 | 
					        test_node = ['test_publisher']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            node_creation_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_node)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(node_creation_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										53
									
								
								tracetools_test/test/test_publisher.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tracetools_test/test/test_publisher.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					publisher_creation_events = [
 | 
				
			||||||
 | 
					    'ros2:rcl_publisher_init',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestPublisher(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_creation(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-publisher-creation'
 | 
				
			||||||
 | 
					        test_node = ['test_publisher']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            publisher_creation_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_node)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(publisher_creation_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										54
									
								
								tracetools_test/test/test_service.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tracetools_test/test/test_service.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					service_creation_events = [
 | 
				
			||||||
 | 
					    'ros2:rcl_service_init',
 | 
				
			||||||
 | 
					    'ros2:rclcpp_service_callback_added',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestService(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_creation(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-service-creation'
 | 
				
			||||||
 | 
					        test_nodes = ['test_service']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            service_creation_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_nodes)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(service_creation_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										54
									
								
								tracetools_test/test/test_service_callback.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tracetools_test/test/test_service_callback.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					service_callback_events = [
 | 
				
			||||||
 | 
					    'ros2:callback_start',
 | 
				
			||||||
 | 
					    'ros2:callback_end',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestServiceCallback(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_callback(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-service-callback'
 | 
				
			||||||
 | 
					        test_nodes = ['test_service_ping', 'test_service_pong']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            service_callback_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_nodes)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(service_callback_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										54
									
								
								tracetools_test/test/test_subscription.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tracetools_test/test/test_subscription.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					subscription_creation_events = [
 | 
				
			||||||
 | 
					    'ros2:rcl_subscription_init',
 | 
				
			||||||
 | 
					    'ros2:rclcpp_subscription_callback_added',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestSubscription(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_creation(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-subscription-creation'
 | 
				
			||||||
 | 
					        test_node = ['test_subscription']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            subscription_creation_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_node)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(subscription_creation_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										54
									
								
								tracetools_test/test/test_subscription_callback.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tracetools_test/test/test_subscription_callback.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					subscription_callback_events = [
 | 
				
			||||||
 | 
					    'ros2:callback_start',
 | 
				
			||||||
 | 
					    'ros2:callback_end',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestSubscriptionCallback(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_callback(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-subscription-callback'
 | 
				
			||||||
 | 
					        test_nodes = ['test_ping', 'test_pong']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            subscription_callback_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_nodes)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(subscription_callback_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										56
									
								
								tracetools_test/test/test_timer.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								tracetools_test/test/test_timer.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tracetools_test.utils import (
 | 
				
			||||||
 | 
					    cleanup_trace,
 | 
				
			||||||
 | 
					    get_trace_event_names,
 | 
				
			||||||
 | 
					    run_and_trace,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASE_PATH = '/tmp'
 | 
				
			||||||
 | 
					PKG = 'tracetools_test'
 | 
				
			||||||
 | 
					timer_events = [
 | 
				
			||||||
 | 
					    'ros2:rcl_timer_init',
 | 
				
			||||||
 | 
					    'ros2:rclcpp_timer_callback_added',
 | 
				
			||||||
 | 
					    'ros2:callback_start',
 | 
				
			||||||
 | 
					    'ros2:callback_end',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestTimer(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_all(self):
 | 
				
			||||||
 | 
					        session_name_prefix = 'session-test-timer-all'
 | 
				
			||||||
 | 
					        test_nodes = ['test_timer']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        exit_code, full_path = run_and_trace(
 | 
				
			||||||
 | 
					            BASE_PATH,
 | 
				
			||||||
 | 
					            session_name_prefix,
 | 
				
			||||||
 | 
					            timer_events,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            PKG,
 | 
				
			||||||
 | 
					            test_nodes)
 | 
				
			||||||
 | 
					        self.assertEqual(exit_code, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        trace_events = get_trace_event_names(full_path)
 | 
				
			||||||
 | 
					        print(f'trace_events: {trace_events}')
 | 
				
			||||||
 | 
					        self.assertSetEqual(set(timer_events), trace_events)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cleanup_trace(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
							
								
								
									
										13
									
								
								tracetools_test/tracetools_test/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tracetools_test/tracetools_test/__init__.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
							
								
								
									
										107
									
								
								tracetools_test/tracetools_test/utils.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								tracetools_test/tracetools_test/utils.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					# Copyright 2019 Robert Bosch GmbH
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""Utils for tracetools_test."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import shutil
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					from typing import List
 | 
				
			||||||
 | 
					from typing import Set
 | 
				
			||||||
 | 
					from typing import Tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import babeltrace
 | 
				
			||||||
 | 
					from launch import LaunchDescription
 | 
				
			||||||
 | 
					from launch import LaunchService
 | 
				
			||||||
 | 
					from launch_ros import get_default_launch_description
 | 
				
			||||||
 | 
					import launch_ros.actions
 | 
				
			||||||
 | 
					from tracetools_trace.tools.lttng import (
 | 
				
			||||||
 | 
					    lttng_destroy,
 | 
				
			||||||
 | 
					    lttng_setup,
 | 
				
			||||||
 | 
					    lttng_start,
 | 
				
			||||||
 | 
					    lttng_stop,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def run_and_trace(
 | 
				
			||||||
 | 
					        base_path: str,
 | 
				
			||||||
 | 
					        session_name_prefix: str,
 | 
				
			||||||
 | 
					        ros_events: List[str],
 | 
				
			||||||
 | 
					        kernel_events: List[str],
 | 
				
			||||||
 | 
					        package_name: str,
 | 
				
			||||||
 | 
					        node_names: List[str]
 | 
				
			||||||
 | 
					    ) -> Tuple[int, str]:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Run a node while tracing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param base_path: the base path where to put the trace directory
 | 
				
			||||||
 | 
					    :param session_name_prefix: the session name prefix for the trace directory
 | 
				
			||||||
 | 
					    :param ros_events: the list of ROS UST events to enable
 | 
				
			||||||
 | 
					    :param kernel_events: the list of kernel events to enable
 | 
				
			||||||
 | 
					    :param package_name: the name of the package to use
 | 
				
			||||||
 | 
					    :param node_names: the names of the nodes to execute
 | 
				
			||||||
 | 
					    :return: exit code, full generated path
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    session_name = f'{session_name_prefix}-{time.strftime("%Y%m%d%H%M%S")}'
 | 
				
			||||||
 | 
					    full_path = os.path.join(base_path, session_name)
 | 
				
			||||||
 | 
					    print(f'trace directory: {full_path}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lttng_setup(session_name, full_path, ros_events=ros_events, kernel_events=kernel_events)
 | 
				
			||||||
 | 
					    lttng_start(session_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nodes = []
 | 
				
			||||||
 | 
					    for node_name in node_names:
 | 
				
			||||||
 | 
					        n = launch_ros.actions.Node(
 | 
				
			||||||
 | 
					            package=package_name,
 | 
				
			||||||
 | 
					            node_executable=node_name,
 | 
				
			||||||
 | 
					            output='screen')
 | 
				
			||||||
 | 
					        nodes.append(n)
 | 
				
			||||||
 | 
					    ld = LaunchDescription(nodes)
 | 
				
			||||||
 | 
					    ls = LaunchService()
 | 
				
			||||||
 | 
					    ls.include_launch_description(get_default_launch_description())
 | 
				
			||||||
 | 
					    ls.include_launch_description(ld)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    exit_code = ls.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lttng_stop(session_name)
 | 
				
			||||||
 | 
					    lttng_destroy(session_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return exit_code, full_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def cleanup_trace(full_path: str) -> None:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Cleanup trace data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param full_path: the full path to the main trace directory
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    shutil.rmtree(full_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_trace_event_names(trace_directory: str) -> Set[str]:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Get a set of event names in a trace.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param trace_directory: the path to the main/top trace directory
 | 
				
			||||||
 | 
					    :return: event names
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    tc = babeltrace.TraceCollection()
 | 
				
			||||||
 | 
					    tc.add_traces_recursive(trace_directory, 'ctf')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    event_names = set()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for event in tc.events:
 | 
				
			||||||
 | 
					        event_names.add(event.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return event_names
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue