From f50b9adb729fc2adfbd0dbbaa09b75d1942e128a Mon Sep 17 00:00:00 2001 From: Alexis Pojomovsky Date: Wed, 17 Oct 2018 10:09:32 -0300 Subject: [PATCH] Converted Markdown files to reStructuredText --- ...d => About-Quality-of-Service-Settings.rst | 139 ++- About-ROS-Interfaces.md | 149 --- About-ROS-Interfaces.rst | 242 +++++ Allocator-Template-Tutorial.md | 227 ----- Allocator-Template-Tutorial.rst | 241 +++++ Alpha-Overview.md => Alpha-Overview.rst | 418 ++++---- Ament-Tutorial.md | 224 ----- Ament-Tutorial.rst | 247 +++++ Beta1-Overview.md | 42 - Beta1-Overview.rst | 57 ++ Beta2-Overview.md | 61 -- Beta2-Overview.rst | 83 ++ Beta3-Overview.md => Beta3-Overview.rst | 58 +- Build-Cop-and-Build-Farmer-Guide.md | 216 ----- Build-Cop-and-Build-Farmer-Guide.rst | 298 ++++++ ...ding-ROS-2-on-Linux-with-Eclipse-Oxygen.md | 128 --- ...ing-ROS-2-on-Linux-with-Eclipse-Oxygen.rst | 248 +++++ ...g-Realtime-rt_preempt-kernel-for-ROS-2.rst | 131 ++- CI-Server-Setup.md | 206 ---- CI-Server-Setup.rst | 223 +++++ Colcon-Tutorial.md | 207 ---- Colcon-Tutorial.rst | 229 +++++ Composition.md | 118 --- Composition.rst | 167 ++++ Contact.md | 31 - Contact.rst | 36 + Contributing.md | 42 - Contributing.rst | 50 + DDS-and-ROS-middleware-implementations.md | 30 - DDS-and-ROS-middleware-implementations.rst | 53 ++ Defining-custom-interfaces-(msg-srv).md | 9 - Defining-custom-interfaces-(msg-srv).rst | 11 + Design-Guide.md => Design-Guide.rst | 99 +- Developer-Guide.md | 591 ------------ Developer-Guide.rst | 709 ++++++++++++++ ...=> Eclipse-Oxygen-with-ROS-2-and-rviz2.rst | 248 ++++- Features.md | 27 - Features.rst | 72 ++ Fedora-Development-Setup.md | 15 - Fedora-Development-Setup.rst | 17 + ...md => Install-Connext-Security-Plugins.rst | 6 +- Installation.md | 19 - Installation.rst | 27 + Intel-ROS2-Projects.md | 16 - Intel-ROS2-Projects.rst | 25 + Intra-Process-Communication.md | 416 -------- Intra-Process-Communication.rst | 459 +++++++++ Introspection-with-command-line-tools.md | 63 -- Introspection-with-command-line-tools.rst | 74 ++ Launch-system.md | 34 - Launch-system.rst | 40 + Linux-Development-Setup.md | 247 ----- Linux-Development-Setup.rst | 280 ++++++ Linux-Install-Binary.md | 108 --- Linux-Install-Binary.rst | 156 +++ Linux-Install-Debians.md | 107 --- Linux-Install-Debians.rst | 125 +++ Logging-and-logger-configuration.md | 104 -- Logging-and-logger-configuration.rst | 119 +++ Logging.md | 73 -- Logging.rst | 94 ++ MISRA-Compliance-Guide.md | 40 - MISRA-Compliance-Guide.rst | 58 ++ Maintaining-a-Source-Checkout.md | 127 --- Maintaining-a-Source-Checkout.rst | 164 ++++ Managed-Nodes.md | 181 ---- Managed-Nodes.rst | 260 +++++ Migration-Guide.md | 822 ---------------- Migration-Guide.rst | 893 ++++++++++++++++++ New-features-in-ROS-2-interfaces-(msg-srv).md | 14 - ...features-in-ROS-2-interfaces-(msg-srv).rst | 17 + Node-arguments.md | 69 -- Node-arguments.rst | 79 ++ OSX-Development-Setup.md | 213 ----- OSX-Development-Setup.rst | 271 ++++++ OSX-Install-Binary.md | 125 --- OSX-Install-Binary.rst | 169 ++++ ...cepts.md => Overview-of-ROS-2-concepts.rst | 64 +- Python-Programming.md | 33 - Python-Programming.rst | 39 + Quality-Guide.md | 160 ---- Quality-Guide.rst | 195 ++++ Quality-of-Service.md | 162 ---- Quality-of-Service.rst | 179 ++++ README.md | 18 +- ...Libraries.md => ROS-2-Client-Libraries.rst | 60 +- ROS-2-On-boarding-Guide.md | 175 ---- ROS-2-On-boarding-Guide.rst | 239 +++++ Rclpy-Import-error-hint.md | 6 - Rclpy-Import-error-hint.rst | 8 + ...rogramming.md => Real-Time-Programming.rst | 181 ++-- Release-Ardent-Apalone.md | 54 -- Release-Ardent-Apalone.rst | 73 ++ Release-Bouncy-Bolson.md | 52 - Release-Bouncy-Bolson.rst | 70 ++ Release-Howto.md | 63 -- Release-Howto.rst | 103 ++ Releases.md | 13 - Releases.rst | 24 + Releasing-a-ROS-2-package-with-bloom.md | 35 - Releasing-a-ROS-2-package-with-bloom.rst | 47 + Roadmap.md | 138 --- Roadmap.rst | 188 ++++ Rosbag-with-ROS1-Bridge.md | 221 ----- Rosbag-with-ROS1-Bridge.rst | 224 +++++ Rosidl-Tutorial.md | 476 ---------- Rosidl-Tutorial.rst | 525 ++++++++++ Run-2-nodes-in-a-single-docker-container.md | 27 - Run-2-nodes-in-a-single-docker-container.rst | 45 + Set-up-a-new-Linux-CI-node.md | 69 -- Set-up-a-new-Linux-CI-node.rst | 93 ++ ...ode.md => Set-up-a-new-Windows-CI-node.rst | 51 +- Set-up-a-new-macOS-CI-node.md | 115 --- Set-up-a-new-macOS-CI-node.rst | 135 +++ Tutorials.md | 66 -- Tutorials.rst | 87 ++ Windows-Development-Setup.md | 334 ------- Windows-Development-Setup.rst | 368 ++++++++ Windows-Install-Binary.md | 206 ---- Windows-Install-Binary.rst | 245 +++++ Working-with-multiple-RMW-implementations.md | 85 -- Working-with-multiple-RMW-implementations.rst | 101 ++ catment.md | 235 ----- catment.rst | 265 ++++++ convert.sh | 3 + dummy-robot-demo.md | 69 -- dummy-robot-demo.rst | 80 ++ tf2.md | 29 - tf2.rst | 39 + 129 files changed, 10590 insertions(+), 8475 deletions(-) rename About-Quality-of-Service-Settings.md => About-Quality-of-Service-Settings.rst (73%) delete mode 100644 About-ROS-Interfaces.md create mode 100644 About-ROS-Interfaces.rst delete mode 100644 Allocator-Template-Tutorial.md create mode 100644 Allocator-Template-Tutorial.rst rename Alpha-Overview.md => Alpha-Overview.rst (54%) delete mode 100644 Ament-Tutorial.md create mode 100644 Ament-Tutorial.rst delete mode 100644 Beta1-Overview.md create mode 100644 Beta1-Overview.rst delete mode 100644 Beta2-Overview.md create mode 100644 Beta2-Overview.rst rename Beta3-Overview.md => Beta3-Overview.rst (51%) delete mode 100644 Build-Cop-and-Build-Farmer-Guide.md create mode 100644 Build-Cop-and-Build-Farmer-Guide.rst delete mode 100644 Building-ROS-2-on-Linux-with-Eclipse-Oxygen.md create mode 100644 Building-ROS-2-on-Linux-with-Eclipse-Oxygen.rst rename Building-Realtime-rt_preempt-kernel-for-ROS-2.md => Building-Realtime-rt_preempt-kernel-for-ROS-2.rst (53%) delete mode 100644 CI-Server-Setup.md create mode 100644 CI-Server-Setup.rst delete mode 100644 Colcon-Tutorial.md create mode 100644 Colcon-Tutorial.rst delete mode 100644 Composition.md create mode 100644 Composition.rst delete mode 100644 Contact.md create mode 100644 Contact.rst delete mode 100644 Contributing.md create mode 100644 Contributing.rst delete mode 100644 DDS-and-ROS-middleware-implementations.md create mode 100644 DDS-and-ROS-middleware-implementations.rst delete mode 100644 Defining-custom-interfaces-(msg-srv).md create mode 100644 Defining-custom-interfaces-(msg-srv).rst rename Design-Guide.md => Design-Guide.rst (52%) delete mode 100644 Developer-Guide.md create mode 100644 Developer-Guide.rst rename Eclipse-Oxygen-with-ROS-2-and-rviz2.md => Eclipse-Oxygen-with-ROS-2-and-rviz2.rst (50%) delete mode 100644 Features.md create mode 100644 Features.rst delete mode 100644 Fedora-Development-Setup.md create mode 100644 Fedora-Development-Setup.rst rename Install-Connext-Security-Plugins.md => Install-Connext-Security-Plugins.rst (54%) delete mode 100644 Installation.md create mode 100644 Installation.rst delete mode 100644 Intel-ROS2-Projects.md create mode 100644 Intel-ROS2-Projects.rst delete mode 100644 Intra-Process-Communication.md create mode 100644 Intra-Process-Communication.rst delete mode 100644 Introspection-with-command-line-tools.md create mode 100644 Introspection-with-command-line-tools.rst delete mode 100644 Launch-system.md create mode 100644 Launch-system.rst delete mode 100644 Linux-Development-Setup.md create mode 100644 Linux-Development-Setup.rst delete mode 100644 Linux-Install-Binary.md create mode 100644 Linux-Install-Binary.rst delete mode 100644 Linux-Install-Debians.md create mode 100644 Linux-Install-Debians.rst delete mode 100644 Logging-and-logger-configuration.md create mode 100644 Logging-and-logger-configuration.rst delete mode 100644 Logging.md create mode 100644 Logging.rst delete mode 100644 MISRA-Compliance-Guide.md create mode 100644 MISRA-Compliance-Guide.rst delete mode 100644 Maintaining-a-Source-Checkout.md create mode 100644 Maintaining-a-Source-Checkout.rst delete mode 100644 Managed-Nodes.md create mode 100644 Managed-Nodes.rst delete mode 100644 Migration-Guide.md create mode 100644 Migration-Guide.rst delete mode 100644 New-features-in-ROS-2-interfaces-(msg-srv).md create mode 100644 New-features-in-ROS-2-interfaces-(msg-srv).rst delete mode 100644 Node-arguments.md create mode 100644 Node-arguments.rst delete mode 100644 OSX-Development-Setup.md create mode 100644 OSX-Development-Setup.rst delete mode 100644 OSX-Install-Binary.md create mode 100644 OSX-Install-Binary.rst rename Overview-of-ROS-2-concepts.md => Overview-of-ROS-2-concepts.rst (63%) delete mode 100644 Python-Programming.md create mode 100644 Python-Programming.rst delete mode 100644 Quality-Guide.md create mode 100644 Quality-Guide.rst delete mode 100644 Quality-of-Service.md create mode 100644 Quality-of-Service.rst rename ROS-2-Client-Libraries.md => ROS-2-Client-Libraries.rst (73%) delete mode 100644 ROS-2-On-boarding-Guide.md create mode 100644 ROS-2-On-boarding-Guide.rst delete mode 100644 Rclpy-Import-error-hint.md create mode 100644 Rclpy-Import-error-hint.rst rename Real-Time-Programming.md => Real-Time-Programming.rst (62%) delete mode 100644 Release-Ardent-Apalone.md create mode 100644 Release-Ardent-Apalone.rst delete mode 100644 Release-Bouncy-Bolson.md create mode 100644 Release-Bouncy-Bolson.rst delete mode 100644 Release-Howto.md create mode 100644 Release-Howto.rst delete mode 100644 Releases.md create mode 100644 Releases.rst delete mode 100644 Releasing-a-ROS-2-package-with-bloom.md create mode 100644 Releasing-a-ROS-2-package-with-bloom.rst delete mode 100644 Roadmap.md create mode 100644 Roadmap.rst delete mode 100644 Rosbag-with-ROS1-Bridge.md create mode 100644 Rosbag-with-ROS1-Bridge.rst delete mode 100644 Rosidl-Tutorial.md create mode 100644 Rosidl-Tutorial.rst delete mode 100644 Run-2-nodes-in-a-single-docker-container.md create mode 100644 Run-2-nodes-in-a-single-docker-container.rst delete mode 100644 Set-up-a-new-Linux-CI-node.md create mode 100644 Set-up-a-new-Linux-CI-node.rst rename Set-up-a-new-Windows-CI-node.md => Set-up-a-new-Windows-CI-node.rst (65%) delete mode 100644 Set-up-a-new-macOS-CI-node.md create mode 100644 Set-up-a-new-macOS-CI-node.rst delete mode 100644 Tutorials.md create mode 100644 Tutorials.rst delete mode 100644 Windows-Development-Setup.md create mode 100644 Windows-Development-Setup.rst delete mode 100644 Windows-Install-Binary.md create mode 100644 Windows-Install-Binary.rst delete mode 100644 Working-with-multiple-RMW-implementations.md create mode 100644 Working-with-multiple-RMW-implementations.rst delete mode 100644 catment.md create mode 100644 catment.rst create mode 100755 convert.sh delete mode 100644 dummy-robot-demo.md create mode 100644 dummy-robot-demo.rst delete mode 100644 tf2.md create mode 100644 tf2.rst diff --git a/About-Quality-of-Service-Settings.md b/About-Quality-of-Service-Settings.rst similarity index 73% rename from About-Quality-of-Service-Settings.md rename to About-Quality-of-Service-Settings.rst index e4905d59c5d..b47ec72b2c2 100644 --- a/About-Quality-of-Service-Settings.md +++ b/About-Quality-of-Service-Settings.rst @@ -1,4 +1,6 @@ -## Overview + +Overview +-------- ROS 2 offers a rich variety of Quality of Service (QoS) policies that allow you to tune communication between nodes. With the right set of Quality of Service policies, ROS 2 can be as reliable as TCP or as best-effort as UDP, with many, many possible states in between. @@ -11,74 +13,93 @@ At the same time, users are given the flexibility to control specific profiles o QoS profiles can be specified for publishers, subscribers, service servers and clients. A QoS profile can be applied independently to each instance of the aforementioned entities, but if different profiles are used it is possible that they will not connect. -## QoS policies +QoS policies +------------ + The base QoS profile currently includes settings for the following policies: -- History - - Keep last: only store up to N samples, configurable via the queue depth option. - - Keep all: store all samples, subject to the configured resource limits of the underlying middleware. -- Depth - - Size of the queue: only honored if used together with “keep last”. -- Reliability - - Best effort: attempt to deliver samples, but may lose them if the network is not robust. - - Reliable: guarantee that samples are delivered, may retry multiple times. -- Durability - - Transient local: the publisher becomes responsible for persisting samples for "late-joining" subscribers. - - Volatile: no attempt is made to persist samples. + +* History + + * Keep last: only store up to N samples, configurable via the queue depth option. + * Keep all: store all samples, subject to the configured resource limits of the underlying middleware. + +* Depth + + * Size of the queue: only honored if used together with “keep last”. + +* Reliability + + * Best effort: attempt to deliver samples, but may lose them if the network is not robust. + * Reliable: guarantee that samples are delivered, may retry multiple times. + +* Durability + + * Transient local: the publisher becomes responsible for persisting samples for "late-joining" subscribers. + * Volatile: no attempt is made to persist samples. For each of the policies there is also the option of “system default”, which uses the default of the underlying middleware which may be defined via DDS vendor tools (e.g. XML configuration files). DDS itself has a wider range of policies that can be configured. These policies have been exposed because of their similarity to features in ROS 1; it is possible that in the future more policies will be exposed in ROS 2. +Comparison to ROS 1 +^^^^^^^^^^^^^^^^^^^ -### Comparison to ROS 1 The history and depth policies in ROS 2 combine to provide functionality akin to the queue size in ROS 1. -The reliability policy in ROS 2 is akin to the use of either UDPROS (only in `roscpp`) for "best effort", or TCPROS (ROS 1 default) for reliable. +The reliability policy in ROS 2 is akin to the use of either UDPROS (only in ``roscpp``\ ) for "best effort", or TCPROS (ROS 1 default) for reliable. Note however that even the reliable policy in ROS 2 is implemented using UDP, which allows for multicasting if appropriate. The durability policy combined with a depth of 1 provides functionality similar to that of "latching" subscribers. +QoS profiles +------------ -## QoS profiles Profiles allow developers to focus on their applications without worrying about every QoS setting possible. A QoS profile defines a set of policies that are expected to go well together for a particular use case. The currently-defined QoS profiles are: -- Default QoS settings for publishers and subscribers + + +* + Default QoS settings for publishers and subscribers In order to make the transition from ROS 1 to ROS 2, exercising a similar network behavior is desirable. By default, publishers and subscribers are reliable in ROS 2, have volatile durability, and "keep last" history. -- Services +* + Services In the same vein as publishers and subscribers, services are reliable. It is especially important for services to use volatile durability, as otherwise service servers that re-start may receive outdated requests. While the client is protected from receiving multiple responses, the server is not protected from side-effects of receiving the outdated requests. -- Sensor data +* + Sensor data For sensor data, in most cases it's more important to receive readings in a timely fashion, rather than ensuring that all of them arrive. That is, developers want the latest samples as soon as they are captured, at the expense of maybe losing some. For that reason the sensor data profile uses best effort reliability and a smaller queue depth. -- Parameters +* + Parameters Parameters in ROS 2 are based on services, and as such have a similar profile. The difference is that parameters use a much larger queue depth so that requests do not get lost when, for example, the parameter client is unable to reach the parameter service server. -- System default +* + System default This uses the system default for all of the policies. - -[Click here](https://github.com/ros2/rmw/blob/release-latest/rmw/include/rmw/qos_profiles.h) for the specific policies in use for the above profiles. +`Click here `__ for the specific policies in use for the above profiles. The settings in these profiles are subject to further tweaks, based on the feedback from the community. While ROS 2 provides some QoS profiles for common use cases, the use of policies that are defined in DDS allows ROS users to take advantage of the vast knowledge base of existing DDS documentation for configuring QoS profiles for their specific use case. +QoS compatibilities +------------------- -## QoS compatibilities **Note:** This section refers to publisher and subscribers but the content applies to service servers and clients in the same manner. QoS profiles may be configured for publishers and subscribers independently. @@ -89,23 +110,59 @@ The stricter of the two policies will be the one used for the connection. The QoS policies exposed in ROS 2 that affect compatibility are the durability and reliability policies. The following tables show the compatibility of the different policy settings and the result: -_Compatibility of QoS durability profiles:_ - -| Publisher | Subscriber | Connection | Result | -| --- | --- | --- | --- | -| Volatile | Volatile | Yes | Volatile | -| Volatile | Transient local | No | - | -| Transient local | Volatile | Yes | Volatile | -| Transient local | Transient local | Yes | Transient local | - -_Compatibility of QoS reliability profiles:_ +*Compatibility of QoS durability profiles:* + +.. list-table:: + :header-rows: 1 + + * - Publisher + - Subscriber + - Connection + - Result + * - Volatile + - Volatile + - Yes + - Volatile + * - Volatile + - Transient local + - No + - - + * - Transient local + - Volatile + - Yes + - Volatile + * - Transient local + - Transient local + - Yes + - Transient local + + +*Compatibility of QoS reliability profiles:* + +.. list-table:: + :header-rows: 1 + + * - Publisher + - Subscriber + - Connection + - Result + * - Best effort + - Best effort + - Yes + - Best effort + * - Best effort + - Reliable + - No + - - + * - Reliable + - Best effort + - Yes + - Best effort + * - Reliable + - Reliable + - Yes + - Reliable -| Publisher | Subscriber | Connection | Result | -| --- | --- | --- | --- | -| Best effort | Best effort | Yes | Best effort | -| Best effort | Reliable | No | - | -| Reliable | Best effort | Yes | Best effort | -| Reliable | Reliable | Yes | Reliable | In order for a connection to be made, all of the policies that affect compatibility must be compatible. -That is, even if a publisher-subscriber pair has compatible reliability QoS profiles, if they have incompatible durability QoS profiles a connection will not be made, and vice-versa. \ No newline at end of file +That is, even if a publisher-subscriber pair has compatible reliability QoS profiles, if they have incompatible durability QoS profiles a connection will not be made, and vice-versa. diff --git a/About-ROS-Interfaces.md b/About-ROS-Interfaces.md deleted file mode 100644 index 096931e1451..00000000000 --- a/About-ROS-Interfaces.md +++ /dev/null @@ -1,149 +0,0 @@ -# ROS Interfaces - -## 1. Background - -ROS applications typically communicate through interfaces of one of two types: messages and services. -ROS uses a simplified description language to describe these interfaces. This description makes it easy for ROS tools to automatically generate source code for the interface type in several target languages. - -In this document we will describe the supported types and how to create your own msg/srv files. - -## 2. Message Description Specification -Messages description are defined in `.msg` files in the `msg/` directory of a ROS package. -`.msg` files are composed of two parts: fields and constants. - -### 2.1 Fields -Each field consists of a type and a name, separated by a space, i.e: -``` -fieldtype1 fieldname1 -fieldtype2 fieldname2 -fieldtype3 fieldname3 -``` - -For example: -``` -int32 my_int -string my_string -``` - -#### 2.1.1 Field Types -Field types can be: -* a built-in-type -* names of Message description defined on their own, such as "geometry_msgs/PoseStamped" - -_built-in-types currently supported:_ - -| Type name | [C++](http://design.ros2.org/articles/generated_interfaces_cpp.html) | [Python](http://design.ros2.org/articles/generated_interfaces_python.html) | [DDS type](http://design.ros2.org/articles/mapping_dds_types.html) -| ------------- | ------------- | ----- | ---- | -| bool | bool | builtins.bool | boolean | -| byte | uint8_t | builtins.bytes* | octet | -| char | char | builtins.str* | char | -| float32 | float | builtins.float* | float | -| float64 | double | builtins.float* | double | -| int8 | int8_t | builtins.int* | octet | -| uint8 | uint8_t | builtins.int* | octet | -| int16 | int16_t | builtins.int* | short | -| uint16 | uint16_t | builtins.int* | unsigned short | -| int32 | int32_t | builtins.int* | long | -| uint32 | uint32_t | builtins.int* | unsigned long | -| int64 | int64_t | builtins.int* | long long | -| uint64 | uint64_t | builtins.int* | unsigned long long | -| string | std::string | builtins.str | string | - - -_Every built-in-type can be used to define arrays:_ - -| Type name | [C++](http://design.ros2.org/articles/generated_interfaces_cpp.html) | [Python](http://design.ros2.org/articles/generated_interfaces_python.html) | [DDS type](http://design.ros2.org/articles/mapping_dds_types.html) -| ------------- | ------------- | ----- | ---- | -| static array | std::array | builtins.list* | T[N] | -| unbounded dynamic array | std::vector | builtins.list | sequence | -| bounded dynamic array | custom_class | builtins.list* | sequence | -| bounded string | std::string | builtins.str* | string | - - - -*All types that are more permissive than their ROS definition enforce the ROS constraints in range and length by software - - -_Example of message definition using arrays and bounded types:_ -``` -int32[] unbounded_integer_array -int32[5] five_integers_array -int32[<=5] up_to_five_integers_array - -string string_of_unbounded_size -string<=10 up_to_ten_characters_string - -string[<=5] up_to_five_unbounded_strings -string<=10[] unbounded_array_of_string_up_to_ten_characters each -string<=10[<=5] up_to_five_strings_up_to_ten_characters_each -``` - -#### 2.1.2 Field Names -Field names must be lowercase alphanumeric characters with underscores for separating words. They must start with an alphabetic character, they must not end with an underscore and never have two consecutive underscores. - -#### 2.1.3 Field Default Value -Default values can be set to any field in the message type. -Currently default values are not supported for string arrays and complex types (i.e. types not present in the built-in-types table above, that applies to all nested messages) - -Defining a default value is done by adding a third element to the field definition line, i.e: -``` -fieldtype fieldname fielddefaultvalue -``` - -For example: -``` -uint8 x 42 -int16 y -2000 -string full_name "John Doe" -int32[] samples [-200, -100, 0, 100, 200] -``` -Note: -- string values must be defined in single `'` or double quotes `"` -- currently string values are not escaped - -### 2.2 Constants -Each constant definition is like a field description with a default value, except that this value can never be changed programatically. This value assignment is indicated by use of an equal '=' sign, e.g. -``` -constanttype CONSTANTNAME=constantvalue -``` -For example: -``` -int32 X=123 -int32 Y=-123 -string FOO="foo" -string EXAMPLE='bar' -``` - -Note: Constants names have to be UPPERCASE - - -## 3. Service Description Specification -Services description are defined in `.srv` files in the `srv/` directory of a ROS package. - -A service description file consists of a request and a response msg type, separated by '---'. Any two .msg files concatenated together with a '---' are a legal service description. - -Here is a very simple example of a service that takes in a string and returns a string: - -``` -string str ---- -string str -``` -We can of course get much more complicated (if you want to refer to a message from the same package you must not mention the package name): - -``` -#request constants -int8 FOO=1 -int8 BAR=2 -#request fields -int8 foobar -another_pkg/AnotherMessage msg ---- -#response constants -uint32 SECRET=123456 -#response fields -another_pkg/YetAnotherMessage val -CustomMessageDefinedInThisPackage value -uint32 an_integer -``` -You cannot embed another service inside of a service. \ No newline at end of file diff --git a/About-ROS-Interfaces.rst b/About-ROS-Interfaces.rst new file mode 100644 index 00000000000..6b3ef837f3f --- /dev/null +++ b/About-ROS-Interfaces.rst @@ -0,0 +1,242 @@ + +ROS Interfaces +============== + +1. Background +------------- + +ROS applications typically communicate through interfaces of one of two types: messages and services. +ROS uses a simplified description language to describe these interfaces. This description makes it easy for ROS tools to automatically generate source code for the interface type in several target languages. + +In this document we will describe the supported types and how to create your own msg/srv files. + +2. Message Description Specification +------------------------------------ + +Messages description are defined in ``.msg`` files in the ``msg/`` directory of a ROS package. +``.msg`` files are composed of two parts: fields and constants. + +2.1 Fields +^^^^^^^^^^ + +Each field consists of a type and a name, separated by a space, i.e: + +.. code-block:: + + fieldtype1 fieldname1 + fieldtype2 fieldname2 + fieldtype3 fieldname3 + +For example: + +.. code-block:: + + int32 my_int + string my_string + +2.1.1 Field Types +~~~~~~~~~~~~~~~~~ + +Field types can be: + + +* a built-in-type +* names of Message description defined on their own, such as "geometry_msgs/PoseStamped" + +*built-in-types currently supported:* + +.. list-table:: + :header-rows: 1 + + * - Type name + - `C++ `__ + - `Python `__ + - `DDS type `__ + * - bool + - bool + - builtins.bool + - boolean + * - byte + - uint8_t + - builtins.bytes* + - octet + * - char + - char + - builtins.str* + - char + * - float32 + - float + - builtins.float* + - float + * - float64 + - double + - builtins.float* + - double + * - int8 + - int8_t + - builtins.int* + - octet + * - uint8 + - uint8_t + - builtins.int* + - octet + * - int16 + - int16_t + - builtins.int* + - short + * - uint16 + - uint16_t + - builtins.int* + - unsigned short + * - int32 + - int32_t + - builtins.int* + - long + * - uint32 + - uint32_t + - builtins.int* + - unsigned long + * - int64 + - int64_t + - builtins.int* + - long long + * - uint64 + - uint64_t + - builtins.int* + - unsigned long long + * - string + - std::string + - builtins.str + - string + + +*Every built-in-type can be used to define arrays:* + +.. list-table:: + :header-rows: 1 + + * - Type name + - `C++ `__ + - `Python `__ + - `DDS type `__ + * - static array + - std::array + - builtins.list* + - T[N] + * - unbounded dynamic array + - std::vector + - builtins.list + - sequence + * - bounded dynamic array + - custom_class + - builtins.list* + - sequence + * - bounded string + - std::string + - builtins.str* + - string + + +*All types that are more permissive than their ROS definition enforce the ROS constraints in range and length by software + +*Example of message definition using arrays and bounded types:* + +.. code-block:: + + int32[] unbounded_integer_array + int32[5] five_integers_array + int32[<=5] up_to_five_integers_array + + string string_of_unbounded_size + string<=10 up_to_ten_characters_string + + string[<=5] up_to_five_unbounded_strings + string<=10[] unbounded_array_of_string_up_to_ten_characters each + string<=10[<=5] up_to_five_strings_up_to_ten_characters_each + +2.1.2 Field Names +~~~~~~~~~~~~~~~~~ + +Field names must be lowercase alphanumeric characters with underscores for separating words. They must start with an alphabetic character, they must not end with an underscore and never have two consecutive underscores. + +2.1.3 Field Default Value +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Default values can be set to any field in the message type. +Currently default values are not supported for string arrays and complex types (i.e. types not present in the built-in-types table above, that applies to all nested messages) + +Defining a default value is done by adding a third element to the field definition line, i.e: + +.. code-block:: + + fieldtype fieldname fielddefaultvalue + +For example: + +.. code-block:: + + uint8 x 42 + int16 y -2000 + string full_name "John Doe" + int32[] samples [-200, -100, 0, 100, 200] + +Note: + + +* string values must be defined in single ``'`` or double quotes ``"`` +* currently string values are not escaped + +2.2 Constants +^^^^^^^^^^^^^ + +Each constant definition is like a field description with a default value, except that this value can never be changed programatically. This value assignment is indicated by use of an equal '=' sign, e.g. + +.. code-block:: + + constanttype CONSTANTNAME=constantvalue + +For example: + +.. code-block:: + + int32 X=123 + int32 Y=-123 + string FOO="foo" + string EXAMPLE='bar' + +Note: Constants names have to be UPPERCASE + +3. Service Description Specification +------------------------------------ + +Services description are defined in ``.srv`` files in the ``srv/`` directory of a ROS package. + +A service description file consists of a request and a response msg type, separated by '---'. Any two .msg files concatenated together with a '---' are a legal service description. + +Here is a very simple example of a service that takes in a string and returns a string: + +.. code-block:: + + string str + --- + string str + +We can of course get much more complicated (if you want to refer to a message from the same package you must not mention the package name): + +.. code-block:: + + #request constants + int8 FOO=1 + int8 BAR=2 + #request fields + int8 foobar + another_pkg/AnotherMessage msg + --- + #response constants + uint32 SECRET=123456 + #response fields + another_pkg/YetAnotherMessage val + CustomMessageDefinedInThisPackage value + uint32 an_integer + +You cannot embed another service inside of a service. diff --git a/Allocator-Template-Tutorial.md b/Allocator-Template-Tutorial.md deleted file mode 100644 index 862c9bc5c90..00000000000 --- a/Allocator-Template-Tutorial.md +++ /dev/null @@ -1,227 +0,0 @@ -This tutorial will teach you how to integrate a custom allocator for publishers and subscribers so that the default heap allocator is never called while your ROS nodes are executing. -The code for this tutorial is available [here](https://github.com/ros2/demos/blob/master/demo_nodes_cpp/src/topics/allocator_tutorial.cpp). - -## Background -Suppose you want to write real-time safe code, and you've heard about the many dangers of calling "new" during the real-time critical section, because the default heap allocator on most platforms is nondeterministic. - -By default, many C++ standard library structures will implicitly allocate memory as they grow, such as `std::vector`. However, these data structures also accept an "Allocator" template argument. If you specify a custom allocator to one of these data structures, it will use that allocator for you instead of the system allocator to grow or shrink the data structure. Your custom allocator could have a pool of memory preallocated on the stack, which might be better suited to real-time applications. - -In the ROS 2 C++ client library (rclcpp), we are following a similar philosophy to the C++ standard library. Publishers, subscribers, and the Executor accept an Allocator template parameter that controls allocations made by that entity during execution. - -## Writing an allocator -To write an allocator compatible with ROS 2's allocator interface, your allocator must be compatible with the C++ standard library allocator interface. - -The C++11 library provides something called `allocator_traits`. The C++11 standard specifies that a custom allocator only needs to fulfil a minimal set of requirements to be used to allocate and deallocate memory in a standard way. `allocator_traits` is a generic structure that fills out other qualities of an allocator based on an allocator written with the minimal requirements. - -For example, the following declaration for a custom allocator would satisfy `allocator_traits` (of course, you would still need to implement the declared functions in this struct): - -``` -template -struct custom_allocator { - using value_type = T; - custom_allocator() noexcept; - template custom_allocator (const custom_allocator&) noexcept; - T* allocate (std::size_t n); - void deallocate (T* p, std::size_t n); -}; - -template -constexpr bool operator== (const custom_allocator&, const custom_allocator&) noexcept; - -template -constexpr bool operator!= (const custom_allocator&, const custom_allocator&) noexcept; -``` - -You could then access other functions and members of the allocator filled in by `allocator_traits` like so: `std::allocator_traits>::construct(...)` - -To learn about the full capabilities of `allocator_traits`, see: http://en.cppreference.com/w/cpp/memory/allocator_traits - -However, some compilers that only have partial C++11 support, such as GCC 4.8, still require allocators to implement a lot of boilerplate code to work with standard library structures such as vectors and strings, because these structures do not use `allocator_traits` internally. Therefore, if you're using a compiler with partial C++11 support, your allocator will need to look more like this: - -``` -template -struct pointer_traits { - using reference = T &; - using const_reference = const T &; -}; - -// Avoid declaring a reference to void with an empty specialization -template<> -struct pointer_traits { -}; - -template -struct MyAllocator : public pointer_traits { -public: - using value_type = T; - using size_type = std::size_t; - using pointer = T *; - using const_pointer = const T *; - using difference_type = typename std::pointer_traits::difference_type; - - MyAllocator() noexcept; - - ~MyAllocator() noexcept; - - template - MyAllocator(const MyAllocator &) noexcept; - - T * allocate(size_t size, const void * = 0); - - void deallocate(T * ptr, size_t size); - - template - struct rebind { - typedef MyAllocator other; - }; -}; - -template -constexpr bool operator==(const MyAllocator &, - const MyAllocator &) noexcept; - -template -constexpr bool operator!=(const MyAllocator &, - const MyAllocator &) noexcept; -``` - -## Writing an example main -Once you have written a valid C++ allocator, you must pass it as a shared pointer to your publisher, subscriber, and executor. - -``` - auto alloc = std::make_shared>(); - auto publisher = node->create_publisher("allocator_example", 10, alloc); - auto msg_mem_strat = - std::make_shared>>(alloc); - auto subscriber = node->create_subscription( - "allocator_example", 10, callback, nullptr, false, msg_mem_strat, alloc); - - std::shared_ptr memory_strategy = - std::make_shared>>(alloc); - rclcpp::executors::SingleThreadedExecutor executor(memory_strategy); -``` - -You will also need to use your allocator to allocate any messages that you pass along the execution codepath. - -``` - auto alloc = std::make_shared>(); -``` - -Once you've instantiated the node and added the executor to the node, it's time to spin: - -``` - uint32_t i = 0; - while (rclcpp::ok()) { - msg->data = i; - i++; - publisher->publish(msg); - rclcpp::utilities::sleep_for(std::chrono::milliseconds(1)); - executor.spin_some(); - } -``` - -## Passing an allocator to the intra-process pipeline -Even though we instantiated a publisher and subscriber in the same process, we aren't using the intra-process pipeline yet. - -The IntraProcessManager is a class that is usually hidden from the user, but in order to pass a custom allocator to it we need to expose it by getting it from the rclcpp Context. The IntraProcessManager makes use of several standard library structures, so without a custom allocator it will call the default new. - -``` - auto context = rclcpp::contexts::default_context::get_global_default_context(); - auto ipm_state = - std::make_shared>>(); - // Constructs the intra-process manager with a custom allocator. - context->get_sub_context(ipm_state); - auto node = rclcpp::Node::make_shared("allocator_example", true); -``` - -Make sure to instantiate publishers and subscribers AFTER constructing the node in this way. - -## Testing and verifying the code -How do you know that your custom allocator is actually getting called? - -The obvious thing to do would be to count the calls made to your custom allocator's `allocate` and `deallocate` functions and compare that to the calls to `new` and `delete`. - -Adding counting to the custom allocator is easy: - -``` - T * allocate(size_t size, const void * = 0) { - // ... - num_allocs++; - // ... - } - - void deallocate(T * ptr, size_t size) { - // ... - num_deallocs++; - // ... - } -``` - -You can also override the global new and delete operators: - -``` -void operator delete(void * ptr) noexcept { - if (ptr != nullptr) { - if (is_running) { - global_runtime_deallocs++; - } - std::free(ptr); - ptr = nullptr; - } -} - -void operator delete(void * ptr, size_t) noexcept { - if (ptr != nullptr) { - if (is_running) { - global_runtime_deallocs++; - } - std::free(ptr); - ptr = nullptr; - } -} -``` - -where the variables we are incrementing are just global static integers, and `is_running` is a global static boolean that gets toggled right before the call to `spin`. - -The [example executable](https://github.com/ros2/demos/blob/master/demo_nodes_cpp/src/topics/allocator_tutorial.cpp) prints the value of the variables. To run the example executable, use: -``` -allocator_example -``` -or, to run the example with the intra-process pipeline on: -``` -allocator_example intra-process -``` - -You should get numbers like: - -``` -Global new was called 15590 times during spin -Global delete was called 15590 times during spin -Allocator new was called 27284 times during spin -Allocator delete was called 27281 times during spin -``` - -We've caught about 2/3 of the allocations/deallocations that happen on the execution path, but where do the remaining 1/3 come from? - -As a matter of fact, these allocations/deallocations originate in the underlying DDS implementation used in this example. - -Proving this is out of the scope of this tutorial, but you can check out the test for the allocation path that gets run as part of the ROS 2 continuous integration testing, which backtraces through the code and figures out whether certain function calls originate in the rmw implementation or in a DDS implementation: - -https://github.com/ros2/realtime_support/blob/master/tlsf_cpp/test/test_tlsf.cpp#L41 - -Note that this test is not using the custom allocator we just created, but the TLSF allocator (see below). - - -## The TLSF allocator - -ROS 2 offers support for the TLSF (Two Level Segregate Fit) allocator, which was designed to meet real-time requirements: - -https://github.com/ros2/realtime_support/tree/master/tlsf_cpp - -For more information about TLSF, see http://www.gii.upv.es/tlsf/ - -Note that the TLSF allocator is licensed under a dual-GPL/LGPL license. - -A full working example using the TLSF allocator is here: -https://github.com/ros2/realtime_support/blob/master/tlsf_cpp/example/allocator_example.cpp \ No newline at end of file diff --git a/Allocator-Template-Tutorial.rst b/Allocator-Template-Tutorial.rst new file mode 100644 index 00000000000..93da8651c71 --- /dev/null +++ b/Allocator-Template-Tutorial.rst @@ -0,0 +1,241 @@ + +This tutorial will teach you how to integrate a custom allocator for publishers and subscribers so that the default heap allocator is never called while your ROS nodes are executing. +The code for this tutorial is available `here `__. + +Background +---------- + +Suppose you want to write real-time safe code, and you've heard about the many dangers of calling "new" during the real-time critical section, because the default heap allocator on most platforms is nondeterministic. + +By default, many C++ standard library structures will implicitly allocate memory as they grow, such as ``std::vector``. However, these data structures also accept an "Allocator" template argument. If you specify a custom allocator to one of these data structures, it will use that allocator for you instead of the system allocator to grow or shrink the data structure. Your custom allocator could have a pool of memory preallocated on the stack, which might be better suited to real-time applications. + +In the ROS 2 C++ client library (rclcpp), we are following a similar philosophy to the C++ standard library. Publishers, subscribers, and the Executor accept an Allocator template parameter that controls allocations made by that entity during execution. + +Writing an allocator +-------------------- + +To write an allocator compatible with ROS 2's allocator interface, your allocator must be compatible with the C++ standard library allocator interface. + +The C++11 library provides something called ``allocator_traits``. The C++11 standard specifies that a custom allocator only needs to fulfil a minimal set of requirements to be used to allocate and deallocate memory in a standard way. ``allocator_traits`` is a generic structure that fills out other qualities of an allocator based on an allocator written with the minimal requirements. + +For example, the following declaration for a custom allocator would satisfy ``allocator_traits`` (of course, you would still need to implement the declared functions in this struct): + +.. code-block:: + + template + struct custom_allocator { + using value_type = T; + custom_allocator() noexcept; + template custom_allocator (const custom_allocator&) noexcept; + T* allocate (std::size_t n); + void deallocate (T* p, std::size_t n); + }; + + template + constexpr bool operator== (const custom_allocator&, const custom_allocator&) noexcept; + + template + constexpr bool operator!= (const custom_allocator&, const custom_allocator&) noexcept; + +You could then access other functions and members of the allocator filled in by ``allocator_traits`` like so: ``std::allocator_traits>::construct(...)`` + +To learn about the full capabilities of ``allocator_traits``\ , see: http://en.cppreference.com/w/cpp/memory/allocator_traits + +However, some compilers that only have partial C++11 support, such as GCC 4.8, still require allocators to implement a lot of boilerplate code to work with standard library structures such as vectors and strings, because these structures do not use ``allocator_traits`` internally. Therefore, if you're using a compiler with partial C++11 support, your allocator will need to look more like this: + +.. code-block:: + + template + struct pointer_traits { + using reference = T &; + using const_reference = const T &; + }; + + // Avoid declaring a reference to void with an empty specialization + template<> + struct pointer_traits { + }; + + template + struct MyAllocator : public pointer_traits { + public: + using value_type = T; + using size_type = std::size_t; + using pointer = T *; + using const_pointer = const T *; + using difference_type = typename std::pointer_traits::difference_type; + + MyAllocator() noexcept; + + ~MyAllocator() noexcept; + + template + MyAllocator(const MyAllocator &) noexcept; + + T * allocate(size_t size, const void * = 0); + + void deallocate(T * ptr, size_t size); + + template + struct rebind { + typedef MyAllocator other; + }; + }; + + template + constexpr bool operator==(const MyAllocator &, + const MyAllocator &) noexcept; + + template + constexpr bool operator!=(const MyAllocator &, + const MyAllocator &) noexcept; + +Writing an example main +----------------------- + +Once you have written a valid C++ allocator, you must pass it as a shared pointer to your publisher, subscriber, and executor. + +.. code-block:: + + auto alloc = std::make_shared>(); + auto publisher = node->create_publisher("allocator_example", 10, alloc); + auto msg_mem_strat = + std::make_shared>>(alloc); + auto subscriber = node->create_subscription( + "allocator_example", 10, callback, nullptr, false, msg_mem_strat, alloc); + + std::shared_ptr memory_strategy = + std::make_shared>>(alloc); + rclcpp::executors::SingleThreadedExecutor executor(memory_strategy); + +You will also need to use your allocator to allocate any messages that you pass along the execution codepath. + +.. code-block:: + + auto alloc = std::make_shared>(); + +Once you've instantiated the node and added the executor to the node, it's time to spin: + +.. code-block:: + + uint32_t i = 0; + while (rclcpp::ok()) { + msg->data = i; + i++; + publisher->publish(msg); + rclcpp::utilities::sleep_for(std::chrono::milliseconds(1)); + executor.spin_some(); + } + +Passing an allocator to the intra-process pipeline +-------------------------------------------------- + +Even though we instantiated a publisher and subscriber in the same process, we aren't using the intra-process pipeline yet. + +The IntraProcessManager is a class that is usually hidden from the user, but in order to pass a custom allocator to it we need to expose it by getting it from the rclcpp Context. The IntraProcessManager makes use of several standard library structures, so without a custom allocator it will call the default new. + +.. code-block:: + + auto context = rclcpp::contexts::default_context::get_global_default_context(); + auto ipm_state = + std::make_shared>>(); + // Constructs the intra-process manager with a custom allocator. + context->get_sub_context(ipm_state); + auto node = rclcpp::Node::make_shared("allocator_example", true); + +Make sure to instantiate publishers and subscribers AFTER constructing the node in this way. + +Testing and verifying the code +------------------------------ + +How do you know that your custom allocator is actually getting called? + +The obvious thing to do would be to count the calls made to your custom allocator's ``allocate`` and ``deallocate`` functions and compare that to the calls to ``new`` and ``delete``. + +Adding counting to the custom allocator is easy: + +.. code-block:: + + T * allocate(size_t size, const void * = 0) { + // ... + num_allocs++; + // ... + } + + void deallocate(T * ptr, size_t size) { + // ... + num_deallocs++; + // ... + } + +You can also override the global new and delete operators: + +.. code-block:: + + void operator delete(void * ptr) noexcept { + if (ptr != nullptr) { + if (is_running) { + global_runtime_deallocs++; + } + std::free(ptr); + ptr = nullptr; + } + } + + void operator delete(void * ptr, size_t) noexcept { + if (ptr != nullptr) { + if (is_running) { + global_runtime_deallocs++; + } + std::free(ptr); + ptr = nullptr; + } + } + +where the variables we are incrementing are just global static integers, and ``is_running`` is a global static boolean that gets toggled right before the call to ``spin``. + +The `example executable `__ prints the value of the variables. To run the example executable, use: + +.. code-block:: + + allocator_example + +or, to run the example with the intra-process pipeline on: + +.. code-block:: + + allocator_example intra-process + +You should get numbers like: + +.. code-block:: + + Global new was called 15590 times during spin + Global delete was called 15590 times during spin + Allocator new was called 27284 times during spin + Allocator delete was called 27281 times during spin + +We've caught about 2/3 of the allocations/deallocations that happen on the execution path, but where do the remaining 1/3 come from? + +As a matter of fact, these allocations/deallocations originate in the underlying DDS implementation used in this example. + +Proving this is out of the scope of this tutorial, but you can check out the test for the allocation path that gets run as part of the ROS 2 continuous integration testing, which backtraces through the code and figures out whether certain function calls originate in the rmw implementation or in a DDS implementation: + +https://github.com/ros2/realtime_support/blob/master/tlsf_cpp/test/test_tlsf.cpp#L41 + +Note that this test is not using the custom allocator we just created, but the TLSF allocator (see below). + +The TLSF allocator +------------------ + +ROS 2 offers support for the TLSF (Two Level Segregate Fit) allocator, which was designed to meet real-time requirements: + +https://github.com/ros2/realtime_support/tree/master/tlsf_cpp + +For more information about TLSF, see http://www.gii.upv.es/tlsf/ + +Note that the TLSF allocator is licensed under a dual-GPL/LGPL license. + +A full working example using the TLSF allocator is here: +https://github.com/ros2/realtime_support/blob/master/tlsf_cpp/example/allocator_example.cpp diff --git a/Alpha-Overview.md b/Alpha-Overview.rst similarity index 54% rename from Alpha-Overview.md rename to Alpha-Overview.rst index 87e990d7583..9ea284a6dfb 100644 --- a/Alpha-Overview.md +++ b/Alpha-Overview.rst @@ -1,18 +1,23 @@ -# ROS 2 alpha releases (Aug 2015 - Oct 2016) + +ROS 2 alpha releases (Aug 2015 - Oct 2016) +========================================== This is a merged version of the previously separated pages for the 8 alpha releases of ROS 2. -## ROS 2 alpha8 release (code name *Hook-and-Loop*; October 2016) +ROS 2 alpha8 release (code name *Hook-and-Loop*\ ; October 2016) +------------------------------------------------------------------ -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -### Changes to supported DDS vendors +Changes to supported DDS vendors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -ROS 2 supports multiple middleware implementations (see [this page](DDS-and-ROS-middleware-implementations.md) for more details). +ROS 2 supports multiple middleware implementations (see `this page ` for more details). Until Alpha 8, ROS 2 was supporting ROS middleware implementations for eProsima's Fast RTPS, RTI's Connext and PrismTech's OpenSplice. -To streamline our efforts, as of Alpha 8, Fast RTPS and Connext (static) will be supported, with Fast RTPS ([now Apache 2.0-licensed](http://www.eprosima.com/index.php/company-all/news/61-eprosima-goes-apache)) shipped as the default. +To streamline our efforts, as of Alpha 8, Fast RTPS and Connext (static) will be supported, with Fast RTPS (\ `now Apache 2.0-licensed `__\ ) shipped as the default. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. You should not expect to switch from ROS 1 to ROS 2, nor should you expect to build a new robot control system with ROS 2. @@ -20,26 +25,31 @@ Rather, you should expect to try out some demos, explore the code, and perhaps w The improvements included in this release are: -- Several improvements to Fast RTPS and its rmw implementation - - Support for large (image) messages in Fast RTPS - - `wait_for_service` functionality in Fast RTPS -- Support for all ROS 2 message types in Python and C -- Added support for Quality of Service (QoS) settings in Python -- Fixed various bugs with the previous alpha release -Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +* Several improvements to Fast RTPS and its rmw implementation + * Support for large (image) messages in Fast RTPS + * ``wait_for_service`` functionality in Fast RTPS -## ROS 2 alpha7 release (code name *Glue Gun*; July 2016) +* Support for all ROS 2 message types in Python and C +* Added support for Quality of Service (QoS) settings in Python +* Fixed various bugs with the previous alpha release + +Pretty much anything not listed above is not included in this release. +The next steps are described in the `Roadmap `. -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +ROS 2 alpha7 release (code name *Glue Gun*\ ; July 2016) +---------------------------------------------------------- -### New version of Ubuntu required +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. + +New version of Ubuntu required +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Until Alpha 6 ROS 2 was targeting Ubuntu Trusty Tahr (14.04). As of this Alpha ROS 2 is targeting Ubuntu Xenial Xerus (16.04) to benefit from newer versions of the compiler, CMake, Python, etc. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. You should not expect to switch from ROS 1 to ROS 2, nor should you expect to build a new robot control system with ROS 2. @@ -47,21 +57,26 @@ Rather, you should expect to try out some demos, explore the code, and perhaps w The major features included in this release are: -- Graph API functionality: wait_for_service - - Added interfaces in rclcpp and make use of them in examples, demos, and tests -- Improved support for large messages in both Connext and Fast-RTPS (partial for Fast-RTPS) -- Turtlebot demo using ported code from ROS 1 - - See: https://github.com/ros2/turtlebot2_demo -Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +* Graph API functionality: wait_for_service + * Added interfaces in rclcpp and make use of them in examples, demos, and tests -## ROS 2 alpha6 release (code name *Fastener*; June 2016) +* Improved support for large messages in both Connext and Fast-RTPS (partial for Fast-RTPS) +* Turtlebot demo using ported code from ROS 1 -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). + * See: https://github.com/ros2/turtlebot2_demo -### Scope +Pretty much anything not listed above is not included in this release. +The next steps are described in the `Roadmap `. + +ROS 2 alpha6 release (code name *Fastener*\ ; June 2016) +---------------------------------------------------------- + +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. + +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -73,24 +88,29 @@ your own demos. The major features included in this release are: -- Graph API functionality: wait_for_service - - Added graph guard condition to nodes for waiting on graph changes - - Added `rmw_service_server_is_available` for verifying if a service is available -- Refactored `rclcpp` to use `rcl` -- Improved support for complex message types in Python - - Nested messages - - Arrays - - Strings -Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +* Graph API functionality: wait_for_service + + * Added graph guard condition to nodes for waiting on graph changes + * Added ``rmw_service_server_is_available`` for verifying if a service is available +* Refactored ``rclcpp`` to use ``rcl`` +* Improved support for complex message types in Python -## ROS 2 alpha5 release (code name *Epoxy*; April 2016) + * Nested messages + * Arrays + * Strings -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Pretty much anything not listed above is not included in this release. +The next steps are described in the `Roadmap `. -### Scope +ROS 2 alpha5 release (code name *Epoxy*\ ; April 2016) +-------------------------------------------------------- + +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. + +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -102,58 +122,65 @@ your own demos. The major features included in this release are: -- Support for C data structures in Fast RTPS and Connext Dynamic rmw implementations. -- Support services in C. -- Added 32-bit and 64-bit ARM as experimentally supported platforms. + +* Support for C data structures in Fast RTPS and Connext Dynamic rmw implementations. +* Support services in C. +* Added 32-bit and 64-bit ARM as experimentally supported platforms. Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. +ROS 2 alpha4 release (code name *Duct tape*\ ; February 2016) +--------------------------------------------------------------- -## ROS 2 alpha4 release (code name *Duct tape*; February 2016) +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Table of Contents +^^^^^^^^^^^^^^^^^ -### Table of Contents -- [Background](#background) -- [Status](#status) -- [Intended audience](#intended-audience) -- [Scope](#scope) -- [Contact us](#contact-us) +* `Background <#background>` +* `Status <#status>` +* `Intended audience <#intended-audience>` +* `Scope <#scope>` +* `Contact us <#contact-us>` -### Background +Background +^^^^^^^^^^ -As explained in a [design -article](http://design.ros2.org/articles/why_ros2.html), we are engaged in +As explained in a `design +article `__\ , we are engaged in the development of a new major version of ROS, called "ROS 2." While the underlying concepts (e.g., publish / subscribe messaging) and goals (e.g., flexibility and reusability) are the same as for ROS 1, we are taking this opportunity to make substantial changes to the system, including changing some of the core APIs. For a deeper treatment of those changes and their -rationale, consult the other [ROS 2 design -articles](http://design.ros2.org). +rationale, consult the other `ROS 2 design +articles `__. -### Status +Status +^^^^^^ On February 17, 2016, we are releasing ROS 2 alpha4, code-named **Duct tape**. Our primary goal with this release is to add more features, while also addressing the feedback we received for the previous releases. -To that end, we built a set of [demos](Tutorials) that +To that end, we built a set of `demos ` that show some of the key features of ROS 2. We encourage you to try out those -demos, look at the code that implements them, and [provide -feedback](#contact-us). +demos, look at the code that implements them, and `provide +feedback <#contact-us>`. We're especially interested to know how well (or poorly) we're addressing use cases that are important to you. -### Intended audience +Intended audience +^^^^^^^^^^^^^^^^^ While everyone is welcome to try out the demos and look through the code, we're aiming this release at people who are already experienced with ROS 1 development. At this point, the ROS 2 documentation is pretty sparse and much of the system is explained by way of how it compares to ROS 1. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -165,59 +192,67 @@ your own demos. The major features included in this release are: -- Improved type support infrastructure, including support for C -- Preliminary Python client library, only publishers and subscriptions are supported. Beware, the API is subject to change and is far from complete! -- Added structures for ROS time in C API (still needs C++ API) - - New concept of extensible "time sources" for ROS Time, the default time source will be like ROS 1 (implementation pending) + +* Improved type support infrastructure, including support for C +* Preliminary Python client library, only publishers and subscriptions are supported. Beware, the API is subject to change and is far from complete! +* Added structures for ROS time in C API (still needs C++ API) + + * New concept of extensible "time sources" for ROS Time, the default time source will be like ROS 1 (implementation pending) Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. +ROS 2 alpha4 release (code name *Duct tape*\ ; February 2016) +--------------------------------------------------------------- -## ROS 2 alpha4 release (code name *Duct tape*; February 2016) +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Table of Contents +^^^^^^^^^^^^^^^^^ -### Table of Contents -- [Background](#background) -- [Status](#status) -- [Intended audience](#intended-audience) -- [Scope](#scope) -- [Contact us](#contact-us) +* `Background <#background>` +* `Status <#status>` +* `Intended audience <#intended-audience>` +* `Scope <#scope>` +* `Contact us <#contact-us>` -### Background +Background +^^^^^^^^^^ -As explained in a [design -article](http://design.ros2.org/articles/why_ros2.html), we are engaged in +As explained in a `design +article `__\ , we are engaged in the development of a new major version of ROS, called "ROS 2." While the underlying concepts (e.g., publish / subscribe messaging) and goals (e.g., flexibility and reusability) are the same as for ROS 1, we are taking this opportunity to make substantial changes to the system, including changing some of the core APIs. For a deeper treatment of those changes and their -rationale, consult the other [ROS 2 design -articles](http://design.ros2.org). +rationale, consult the other `ROS 2 design +articles `__. -### Status +Status +^^^^^^ On February 17, 2016, we are releasing ROS 2 alpha4, code-named **Duct tape**. Our primary goal with this release is to add more features, while also addressing the feedback we received for the previous releases. -To that end, we built a set of [demos](Tutorials) that +To that end, we built a set of `demos ` that show some of the key features of ROS 2. We encourage you to try out those -demos, look at the code that implements them, and [provide -feedback](#contact-us). +demos, look at the code that implements them, and `provide +feedback <#contact-us>`. We're especially interested to know how well (or poorly) we're addressing use cases that are important to you. -### Intended audience +Intended audience +^^^^^^^^^^^^^^^^^ While everyone is welcome to try out the demos and look through the code, we're aiming this release at people who are already experienced with ROS 1 development. At this point, the ROS 2 documentation is pretty sparse and much of the system is explained by way of how it compares to ROS 1. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -229,59 +264,67 @@ your own demos. The major features included in this release are: -- Improved type support infrastructure, including support for C -- Preliminary Python client library, only publishers and subscriptions are supported. Beware, the API is subject to change and is far from complete! -- Added structures for ROS time in C API (still needs C++ API) - - New concept of extensible "time sources" for ROS Time, the default time source will be like ROS 1 (implementation pending) + +* Improved type support infrastructure, including support for C +* Preliminary Python client library, only publishers and subscriptions are supported. Beware, the API is subject to change and is far from complete! +* Added structures for ROS time in C API (still needs C++ API) + + * New concept of extensible "time sources" for ROS Time, the default time source will be like ROS 1 (implementation pending) Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. +ROS 2 alpha3 release (code name *Cement*\ ; December 2015) +------------------------------------------------------------ -## ROS 2 alpha3 release (code name *Cement*; December 2015) +Welcome to the latest release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -Welcome to the latest release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Table of Contents +^^^^^^^^^^^^^^^^^ -### Table of Contents -- [Background](#background) -- [Status](#status) -- [Intended audience](#intended-audience) -- [Scope](#scope) -- [Contact us](#contact-us) +* `Background <#background>` +* `Status <#status>` +* `Intended audience <#intended-audience>` +* `Scope <#scope>` +* `Contact us <#contact-us>` -### Background +Background +^^^^^^^^^^ -As explained in a [design -article](http://design.ros2.org/articles/why_ros2.html), we are engaged in +As explained in a `design +article `__\ , we are engaged in the development of a new major version of ROS, called "ROS 2." While the underlying concepts (e.g., publish / subscribe messaging) and goals (e.g., flexibility and reusability) are the same as for ROS 1, we are taking this opportunity to make substantial changes to the system, including changing some of the core APIs. For a deeper treatment of those changes and their -rationale, consult the other [ROS 2 design -articles](http://design.ros2.org). +rationale, consult the other `ROS 2 design +articles `__. -### Status +Status +^^^^^^ On December 18, 2015, we are releasing ROS 2 alpha3, code-named **Cement**. Our primary goal with this release is to add more features, while also addressing the feedback we received for the previous releases. -To that end, we built a set of [demos](Tutorials) that +To that end, we built a set of `demos ` that show some of the key features of ROS 2. We encourage you to try out those -demos, look at the code that implements them, and [provide -feedback](#contact-us). +demos, look at the code that implements them, and `provide +feedback <#contact-us>`. We're especially interested to know how well (or poorly) we're addressing use cases that are important to you. -### Intended audience +Intended audience +^^^^^^^^^^^^^^^^^ While everyone is welcome to try out the demos and look through the code, we're aiming this release at people who are already experienced with ROS 1 development. At this point, the ROS 2 documentation is pretty sparse and much of the system is explained by way of how it compares to ROS 1. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -293,67 +336,76 @@ your own demos. The major features included in this release are: -- Updated `rcl` interface. - - This interface will be wrapped in order to create language bindings, e.g. `rclpy`. - - This interface has improved documentation and test coverage over existing interfaces we currently have, e.g. `rmw` and `rclcpp`. - - See: https://github.com/ros2/rcl/tree/release-alpha3/rcl/include/rcl -- Added support in rclcpp for using the TLSF (two-level segregate fit) allocator, a memory allocator design for embedded and real-time systems. -- Improved efficiency of MultiThreadedExecutor and fixed numerous bugs with multi-threaded execution, which is now test on CI. -- Added ability to cancel an Executor from within a callback called in spin. -- Added ability for a timer to cancel itself by supporting a Timer callback that accepts a reference to itself as a function parameter. -- Added checks for disallowing multiple threads to enter Executor::spin. -- Improved reliability of numerous tests that had been sporadically failing. -- Added support for using FastRTPS (instead of, e.g., OpenSplice or Connext). -- A partial port of tf2 including the core libraries and core command line tools. + +* Updated ``rcl`` interface. + + * This interface will be wrapped in order to create language bindings, e.g. ``rclpy``. + * This interface has improved documentation and test coverage over existing interfaces we currently have, e.g. ``rmw`` and ``rclcpp``. + * See: https://github.com/ros2/rcl/tree/release-alpha3/rcl/include/rcl + +* Added support in rclcpp for using the TLSF (two-level segregate fit) allocator, a memory allocator design for embedded and real-time systems. +* Improved efficiency of MultiThreadedExecutor and fixed numerous bugs with multi-threaded execution, which is now test on CI. +* Added ability to cancel an Executor from within a callback called in spin. +* Added ability for a timer to cancel itself by supporting a Timer callback that accepts a reference to itself as a function parameter. +* Added checks for disallowing multiple threads to enter Executor::spin. +* Improved reliability of numerous tests that had been sporadically failing. +* Added support for using FastRTPS (instead of, e.g., OpenSplice or Connext). +* A partial port of tf2 including the core libraries and core command line tools. Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. +ROS 2 alpha2 release (code name *Baling wire*\ ; October 2015) +---------------------------------------------------------------- -## ROS 2 alpha2 release (code name *Baling wire*; October 2015) +Welcome to the second release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -Welcome to the second release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Table of Contents +^^^^^^^^^^^^^^^^^ -### Table of Contents -- [Background](#background) -- [Status](#status) -- [Intended audience](#intended-audience) -- [Scope](#scope) -- [Contact us](#contact-us) +* `Background <#background>` +* `Status <#status>` +* `Intended audience <#intended-audience>` +* `Scope <#scope>` +* `Contact us <#contact-us>` -### Background +Background +^^^^^^^^^^ -As explained in a [design -article](http://design.ros2.org/articles/why_ros2.html), we are engaged in +As explained in a `design +article `__\ , we are engaged in the development of a new major version of ROS, called "ROS 2." While the underlying concepts (e.g., publish / subscribe messaging) and goals (e.g., flexibility and reusability) are the same as for ROS 1, we are taking this opportunity to make substantial changes to the system, including changing some of the core APIs. For a deeper treatment of those changes and their -rationale, consult the other [ROS 2 design -articles](http://design.ros2.org). +rationale, consult the other `ROS 2 design +articles `__. -### Status +Status +^^^^^^ On November 3, 2015, we are releasing ROS 2 alpha2, code-named **Baling wire**. Our primary goal with this release is to add more features, while also addressing the feedback we received for the previous alpha 1 release. -To that end, we built a set of [demos](Tutorials) that +To that end, we built a set of `demos ` that show some of the key features of ROS 2. We encourage you to try out those -demos, look at the code that implements them, and [provide -feedback](#contact-us). +demos, look at the code that implements them, and `provide +feedback <#contact-us>`. We're especially interested to know how well (or poorly) we're addressing use cases that are important to you. -### Intended audience +Intended audience +^^^^^^^^^^^^^^^^^ While everyone is welcome to try out the demos and look through the code, we're aiming this release at people who are already experienced with ROS 1 development. At this point, the ROS 2 documentation is pretty sparse and much of the system is explained by way of how it compares to ROS 1. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -365,61 +417,68 @@ your own demos. The major features included in this release are: -- Support for custom allocators in rclcpp, useful for real-time messaging -- Feature parity of Windows with Linux/OSX, including workspace management, services and parameters -- rclcpp API improvements -- FreeRTPS improvements + +* Support for custom allocators in rclcpp, useful for real-time messaging +* Feature parity of Windows with Linux/OSX, including workspace management, services and parameters +* rclcpp API improvements +* FreeRTPS improvements Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. +ROS 2 alpha1 release (code name *Anchor*\ ; August 2015) +---------------------------------------------------------- -## ROS 2 alpha1 release (code name *Anchor*; August 2015) +Welcome to the first release of ROS 2 software! We hope that you try it out and `provide feedback <#contact-us>`. -Welcome to the first release of ROS 2 software! We hope that you try it out and [provide feedback](#contact-us). +Table of Contents +^^^^^^^^^^^^^^^^^ -### Table of Contents -- [Background](#background) -- [Status](#status) -- [Intended audience](#intended-audience) -- [Scope](#scope) -- [Contact us](#contact-us) +* `Background <#background>` +* `Status <#status>` +* `Intended audience <#intended-audience>` +* `Scope <#scope>` +* `Contact us <#contact-us>` -### Background +Background +^^^^^^^^^^ -As explained in a [design -article](http://design.ros2.org/articles/why_ros2.html), we are engaged in +As explained in a `design +article `__\ , we are engaged in the development of a new major version of ROS, called "ROS 2." While the underlying concepts (e.g., publish / subscribe messaging) and goals (e.g., flexibility and reusability) are the same as for ROS 1, we are taking this opportunity to make substantial changes to the system, including changing some of the core APIs. For a deeper treatment of those changes and their -rationale, consult the other [ROS 2 design -articles](http://design.ros2.org). +rationale, consult the other `ROS 2 design +articles `__. -### Status +Status +^^^^^^ On August 31, 2015, we are releasing ROS 2 alpha1, code-named **Anchor**. Our primary goal with this release is to give you the opportunity to understand how ROS 2 works, in particular how it differs from ROS 1. -To that end, we built a set of [demos](Tutorials) that +To that end, we built a set of `demos ` that show some of the key features of ROS 2. We encourage you to try out those -demos, look at the code that implements them, and [provide -feedback](#contact-us). +demos, look at the code that implements them, and `provide +feedback <#contact-us>`. We're especially interested to know how well (or poorly) we're addressing use cases that are important to you. -### Intended audience +Intended audience +^^^^^^^^^^^^^^^^^ While everyone is welcome to try out the demos and look through the code, we're aiming this release at people who are already experienced with ROS 1 development. At this point, the ROS 2 documentation is pretty sparse and much of the system is explained by way of how it compares to ROS 1. -### Scope +Scope +^^^^^ As the "alpha" qualifier suggests, this release of ROS 2 is far from complete. @@ -431,15 +490,16 @@ your own demos. The major features included in this release are: -- Discovery, transport, and serialization [use DDS](http://design.ros2.org/articles/ros_on_dds.html) -- Support [multiple DDS vendors](http://design.ros2.org/articles/ros_on_dds.html#vendors-and-licensing) -- Support messaging primitives: topics (publish / subscribe), services (request / response), and parameters -- Support Linux (Ubuntu Trusty), OS X (Yosemite) and Windows (8) -- [Use quality-of-service settings to handle lossy networks](Quality-Of-Service.md) -- [Communicate inter-process or intra-process with the same API](Intra-Process-Communication.md) -- [Write real-time safe code that uses the ROS 2 APIs](Real-Time-Programming.md) -- [Run ROS 2 on "bare-metal" microcontrollers (no operating system)](https://github.com/ros2/freertps/wiki) -- [Bridge communication between ROS 1 and ROS 2](https://github.com/ros2/ros1_bridge/blob/master/README.md) + +* Discovery, transport, and serialization `use DDS `__ +* Support `multiple DDS vendors `__ +* Support messaging primitives: topics (publish / subscribe), services (request / response), and parameters +* Support Linux (Ubuntu Trusty), OS X (Yosemite) and Windows (8) +* `Use quality-of-service settings to handle lossy networks ` +* `Communicate inter-process or intra-process with the same API ` +* `Write real-time safe code that uses the ROS 2 APIs ` +* `Run ROS 2 on "bare-metal" microcontrollers (no operating system) `__ +* `Bridge communication between ROS 1 and ROS 2 `__ Pretty much anything not listed above is not included in this release. -The next steps are described in the [Roadmap](Roadmap.md). +The next steps are described in the `Roadmap `. diff --git a/Ament-Tutorial.md b/Ament-Tutorial.md deleted file mode 100644 index 29bc6e17fe2..00000000000 --- a/Ament-Tutorial.md +++ /dev/null @@ -1,224 +0,0 @@ -**As of ROS 2 Bouncy the recommended build tool is `colcon` described in the [colcon tutorial](Colcon-Tutorial.md).** - -# Overview - -This will provide you with a quick summary of how to get up and running using an ament workspace. -It will be a practical tutorial and is not designed to replace the core documentation. - -## Background - -Ament is an iteration on the catkin meta-build tool. -For more information on the design of ament see [this document](http://design.ros2.org/articles/ament.html). - -The source can be found in the [ament GitHub organization](https://github.com/ament). - -## Prerequisites - -## Development Environment - -Make sure that you have setup your development environment according to the building-from-source [instruction](Installation.md). - -## Basics - -An ament workspace is a directory with a particular structure. -Commonly there is a `src` subdirectory. -Inside that subdirectory is where the source code will be located. -Typically the directory starts otherwise empty. - -Ament does out of source builds. -By default it will create a `build` and `install` directory as peers of the `src` directory. -The `build` directory will be where intermediate files are stored. -For each package a subfolder will be created in which e.g. CMake is being invoked. -The `install` directory is where each package will be installed to. - -NB: Compared to catkin there is no `devel` directory. - -## Create directory structure - -To make the basic structure in the directory `~/ros2_ws`: - -```bash -mkdir -p ~/ros2_ws/src -cd ~/ros2_ws -``` - -This is the directory structure of `~/ros2_ws` that you can expect at this point: - -``` -. -└── src - -1 directory, 0 files -``` - -## Add some sources - -To start off we need to setup an underlay without any of ROS2 installed. - -Note: if you do not have `vcs` installed, instructions are [here](https://github.com/dirk-thomas/vcstool). - -```bash -wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -vcs import src < ros2.repos -``` - -This is the directory structure of `~/ros2_ws` that you can expect after adding sources (note the exact structure and number of directories/files may change over time): - -``` -. -├── ros2.repos -└── src - ├── ament - │   ├── ament_cmake - │   ├── ament_index - | ... - │   ├── osrf_pycommon - │   └── uncrustify - ├── eProsima - │   ├── Fast-CDR - │   └── Fast-RTPS - ├── ros - │   ├── class_loader - │   └── console_bridge - └── ros2 - ├── ament_cmake_ros - ├── common_interfaces - ├── demos - ... - ├── urdfdom - ├── urdfdom_headers - └── vision_opencv - -51 directories, 1 file -``` - -## Run the build - -Since this is a bootstrap environment we need to call ament.py by its full path. - -Note: In the future once ament is either installed on your system or in an underlayed workspace this will no longer be necessary. - -Since there is no `devel` space in ament and it requires installing each package it supports the option `--symlink-install`. -This allows the installed files to be changed by changing the files in the `source` space (e.g. Python files or other not compiled resourced) for faster iteration. - -```bash -src/ament/ament_tools/scripts/ament.py build --build-tests --symlink-install -``` - -## Run the tests - -To run the tests you just built, with the `--build-tests` option above, run the following: - -```bash -src/ament/ament_tools/scripts/ament.py test -``` - -If you have built (and installed) a workspace before including the tests (using `build --build-tests`) you can skip the build and install step to speed up the process: - -```bash -src/ament/ament_tools/scripts/ament.py test --skip-build --skip-install -``` - -## Source the environment - -When ament has completed building successfully the output will be in the `install` directory. -To use the executables and libraries you need to e.g. add the `install/bin` directory to your path. -Ament will have generated bash files in the `install` directory to help setup the environment. -These files will both add the required elements to your path and library paths as well as provide any exported bash or shell commands exported by packages. - -```bash -. install/local_setup.bash -``` - -NB: This is slightly different than catkin. -The `local_setup.*` file is slightly different than the `setup.*` file in that it will only apply settings from the current workspace. -When using more than one workspace you will still source the `setup.*` files to get the environment including all parent workspaces. - -## Try a demo - -With the environment sourced you can now run executables built by ament. - -```bash -ros2 run demo_nodes_cpp listener & -ros2 run demo_nodes_cpp talker -``` - -And you will see the numbers incrementing. - -Lets take down the nodes and try creating our own workspace overlay. - -```bash -^-C -kill %1 -``` - -## Develop your own package - -Ament uses the same `package.xml` specification as defined for catkin in [REP 140](http://www.ros.org/reps/rep-0140.html). - -You can create your own package inside the `src` directory however it is recommended to use an overlay when you are going to iterate only on a few packages. - -## Create an overlay - -Now that you have setup your bootstrap underlay you will also find `ament` is on your path. - -Lets make a new overlay directory `~/ros2_overlay_ws`. - -```bash -mkdir -p ~/ros2_overlay_ws/src -cd ~/ros2_overlay_ws/src -``` - -And to get started we'll overlay the [ros2/examples repository](https://github.com/ros2/examples): - -```bash -# If you know that you're using the latest branch of all -# repositories in the underlay, you can also get the latest -# version of the ros2/examples repository, with this command: -# git clone https://github.com/ros2/examples.git -# Otherwise, clone a copy from the underlay source code: -git clone ~/ros2_ws/src/ros2/examples -``` - -And build the overlay, but let's build with debug so we can make sure to get debug symbols: - -```bash -cd ~/ros2_overlay_ws -ament build --cmake-args -DCMAKE_BUILD_TYPE=Debug -``` - -Now this overlay is on top of the existing overlay so you'll find that `which talker` currently refers to the one from the underlay. - -If you source `~/ros2_overlay_ws/install/local_setup.bash` it will change to refer to talker in the overlay. - -If you are returning with a new terminal to your development and want to pick up developing on your overlay you can simply source `~/ros2_overlay_ws/install/setup.bash` which will source all parent workspaces environments automatically. - -## Create your own package - -You can create your own package. -The equivalent of `catkin_create_package` will be ported to ament but is not available yet. - -Ament supports multiple build types. -The recommended build types are `ament_cmake` and `ament_python`. -Also supported are pure `cmake` packages. -It's expected to add support for more [build types](https://github.com/ament/ament_tools/blob/master/doc/development/build_types.rst). - -An example of an `ament_python` build is the [`ament_tools` package](https://github.com/ament/ament_tools), where the setup.py is the primary entry point for building. - -A package such as [`demo_nodes_cpp`](https://github.com/ros2/demos/tree/master/demo_nodes_cpp) uses the `ament_cmake` build type, and uses CMake as the build tool. - -## Tips - -- If you do not want to build a specific package place an empty file named `AMENT_IGNORE` in the directory and it will not be indexed. - - "Catch all" options like --cmake-args should be placed after other options, or delimited with '--': - -```bash -ament build . --force-cmake-configure --cmake-args -DCMAKE_BUILD_TYPE=Debug -- --ament-cmake-args -DCMAKE_BUILD_TYPE=Release -``` -
- -- If you want to run a single particular test from a package: -``` -ament test --only-packages YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG -``` diff --git a/Ament-Tutorial.rst b/Ament-Tutorial.rst new file mode 100644 index 00000000000..e6c09c474bc --- /dev/null +++ b/Ament-Tutorial.rst @@ -0,0 +1,247 @@ +.. role:: raw-html-m2r(raw) + :format: html + + +**As of ROS 2 Bouncy the recommended build tool is ``colcon`` described in the `colcon tutorial `.** + +Overview +======== + +This will provide you with a quick summary of how to get up and running using an ament workspace. +It will be a practical tutorial and is not designed to replace the core documentation. + +Background +---------- + +Ament is an iteration on the catkin meta-build tool. +For more information on the design of ament see `this document `__. + +The source can be found in the `ament GitHub organization `__. + +Prerequisites +------------- + +Development Environment +----------------------- + +Make sure that you have setup your development environment according to the building-from-source `instruction `. + +Basics +------ + +An ament workspace is a directory with a particular structure. +Commonly there is a ``src`` subdirectory. +Inside that subdirectory is where the source code will be located. +Typically the directory starts otherwise empty. + +Ament does out of source builds. +By default it will create a ``build`` and ``install`` directory as peers of the ``src`` directory. +The ``build`` directory will be where intermediate files are stored. +For each package a subfolder will be created in which e.g. CMake is being invoked. +The ``install`` directory is where each package will be installed to. + +NB: Compared to catkin there is no ``devel`` directory. + +Create directory structure +-------------------------- + +To make the basic structure in the directory ``~/ros2_ws``\ : + +.. code-block:: bash + + mkdir -p ~/ros2_ws/src + cd ~/ros2_ws + +This is the directory structure of ``~/ros2_ws`` that you can expect at this point: + +.. code-block:: + + . + └── src + + 1 directory, 0 files + +Add some sources +---------------- + +To start off we need to setup an underlay without any of ROS2 installed. + +Note: if you do not have ``vcs`` installed, instructions are `here `__. + +.. code-block:: bash + + wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos + vcs import src < ros2.repos + +This is the directory structure of ``~/ros2_ws`` that you can expect after adding sources (note the exact structure and number of directories/files may change over time): + +.. code-block:: + + . + ├── ros2.repos + └── src + ├── ament + │   ├── ament_cmake + │   ├── ament_index + | ... + │   ├── osrf_pycommon + │   └── uncrustify + ├── eProsima + │   ├── Fast-CDR + │   └── Fast-RTPS + ├── ros + │   ├── class_loader + │   └── console_bridge + └── ros2 + ├── ament_cmake_ros + ├── common_interfaces + ├── demos + ... + ├── urdfdom + ├── urdfdom_headers + └── vision_opencv + + 51 directories, 1 file + +Run the build +------------- + +Since this is a bootstrap environment we need to call ament.py by its full path. + +Note: In the future once ament is either installed on your system or in an underlayed workspace this will no longer be necessary. + +Since there is no ``devel`` space in ament and it requires installing each package it supports the option ``--symlink-install``. +This allows the installed files to be changed by changing the files in the ``source`` space (e.g. Python files or other not compiled resourced) for faster iteration. + +.. code-block:: bash + + src/ament/ament_tools/scripts/ament.py build --build-tests --symlink-install + +Run the tests +------------- + +To run the tests you just built, with the ``--build-tests`` option above, run the following: + +.. code-block:: bash + + src/ament/ament_tools/scripts/ament.py test + +If you have built (and installed) a workspace before including the tests (using ``build --build-tests``\ ) you can skip the build and install step to speed up the process: + +.. code-block:: bash + + src/ament/ament_tools/scripts/ament.py test --skip-build --skip-install + +Source the environment +---------------------- + +When ament has completed building successfully the output will be in the ``install`` directory. +To use the executables and libraries you need to e.g. add the ``install/bin`` directory to your path. +Ament will have generated bash files in the ``install`` directory to help setup the environment. +These files will both add the required elements to your path and library paths as well as provide any exported bash or shell commands exported by packages. + +.. code-block:: bash + + . install/local_setup.bash + +NB: This is slightly different than catkin. +The ``local_setup.*`` file is slightly different than the ``setup.*`` file in that it will only apply settings from the current workspace. +When using more than one workspace you will still source the ``setup.*`` files to get the environment including all parent workspaces. + +Try a demo +---------- + +With the environment sourced you can now run executables built by ament. + +.. code-block:: bash + + ros2 run demo_nodes_cpp listener & + ros2 run demo_nodes_cpp talker + +And you will see the numbers incrementing. + +Lets take down the nodes and try creating our own workspace overlay. + +.. code-block:: bash + + ^-C + kill %1 + +Develop your own package +------------------------ + +Ament uses the same ``package.xml`` specification as defined for catkin in `REP 140 `__. + +You can create your own package inside the ``src`` directory however it is recommended to use an overlay when you are going to iterate only on a few packages. + +Create an overlay +----------------- + +Now that you have setup your bootstrap underlay you will also find ``ament`` is on your path. + +Lets make a new overlay directory ``~/ros2_overlay_ws``. + +.. code-block:: bash + + mkdir -p ~/ros2_overlay_ws/src + cd ~/ros2_overlay_ws/src + +And to get started we'll overlay the `ros2/examples repository `__\ : + +.. code-block:: bash + + # If you know that you're using the latest branch of all + # repositories in the underlay, you can also get the latest + # version of the ros2/examples repository, with this command: + # git clone https://github.com/ros2/examples.git + # Otherwise, clone a copy from the underlay source code: + git clone ~/ros2_ws/src/ros2/examples + +And build the overlay, but let's build with debug so we can make sure to get debug symbols: + +.. code-block:: bash + + cd ~/ros2_overlay_ws + ament build --cmake-args -DCMAKE_BUILD_TYPE=Debug + +Now this overlay is on top of the existing overlay so you'll find that ``which talker`` currently refers to the one from the underlay. + +If you source ``~/ros2_overlay_ws/install/local_setup.bash`` it will change to refer to talker in the overlay. + +If you are returning with a new terminal to your development and want to pick up developing on your overlay you can simply source ``~/ros2_overlay_ws/install/setup.bash`` which will source all parent workspaces environments automatically. + +Create your own package +----------------------- + +You can create your own package. +The equivalent of ``catkin_create_package`` will be ported to ament but is not available yet. + +Ament supports multiple build types. +The recommended build types are ``ament_cmake`` and ``ament_python``. +Also supported are pure ``cmake`` packages. +It's expected to add support for more `build types `__. + +An example of an ``ament_python`` build is the `\ ``ament_tools`` package `__\ , where the setup.py is the primary entry point for building. + +A package such as `\ ``demo_nodes_cpp`` `__ uses the ``ament_cmake`` build type, and uses CMake as the build tool. + +Tips +---- + + +* + If you do not want to build a specific package place an empty file named ``AMENT_IGNORE`` in the directory and it will not be indexed. + + "Catch all" options like --cmake-args should be placed after other options, or delimited with '--': + +.. code-block:: bash + + ament build . --force-cmake-configure --cmake-args -DCMAKE_BUILD_TYPE=Debug -- --ament-cmake-args -DCMAKE_BUILD_TYPE=Release + +:raw-html-m2r:`
` + + +* If you want to run a single particular test from a package: + .. code-block:: + + ament test --only-packages YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG diff --git a/Beta1-Overview.md b/Beta1-Overview.md deleted file mode 100644 index 1da4700af84..00000000000 --- a/Beta1-Overview.md +++ /dev/null @@ -1,42 +0,0 @@ -### Beta 1 (codename Asphalt; December 2016) - -Welcome to the latest release of ROS 2 software! We hope that you try it out and provide feedback. - -### Supported Platforms - -We support ROS 2 Beta 1 on three platforms: Ubuntu 16.04 (Xenial), Mac OS X 10.11 (El Capitan), and Windows 8.1 and 10. We provide both binary packages and instructions for how to compile from source for all 3 platforms. - -### Features - -Improvements since the Alpha 8 release: - * Support for node composition at compile, link, or runtime. - * A standard lifecycle for managed nodes. - * Improved support for Quality of Service tuning and tests. - * [New and updated design documents](http://design.ros2.org/) - * More [tutorials](Tutorials.md) and [examples](https://github.com/ros2/examples) - * Bridging services to / from ROS1 (in addition to topics) - -Selected features from previous Alpha releases (for the complete list, see the [earlier release notes](Releases.md)): - * C++ and Python implementations of ROS 2 client libraries including APIs for: - * Publishing and subscribing to ROS topics - * Requesting and replying ROS services (synchronous (C++ only) and asynchronous) - * Getting and setting ROS parameters (C++ only, synchronous and asynchronous) - * Timer callbacks -* Support for interoperability between multiple DDS/RTPS implementations - * eProsima FastRTPS is our default implementation, and is included in the binary packages - * RTI Connext is supported: build from source to try it out - * We initially supported PrismTech OpenSplice but eventually decided to drop it - * A graph API for network events - * Distributed discovery - * Realtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment) - * Support for custom allocators - * ROS 1 <-> ROS 2 dynamic bridge node - * Executor threading model in C++ - * Extended `.msg` format with new features: - * Bounded arrays - * Default values - -Known issues: -* We’re tracking issues in various repositories, but the main entry point is the [ros2/ros2 issue tracker](https://github.com/ros2/ros2/issues) -* We’d like to highlight a [known issue](https://github.com/ros2/rmw_fastrtps/issues/81) that we are working with eProsima to fix that results in significantly degrated performance for large messages under FastRTPS. -This will be observed when running some of the demos with larger image resolutions. diff --git a/Beta1-Overview.rst b/Beta1-Overview.rst new file mode 100644 index 00000000000..09e37d29d20 --- /dev/null +++ b/Beta1-Overview.rst @@ -0,0 +1,57 @@ + +Beta 1 (codename Asphalt; December 2016) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Welcome to the latest release of ROS 2 software! We hope that you try it out and provide feedback. + +Supported Platforms +^^^^^^^^^^^^^^^^^^^ + +We support ROS 2 Beta 1 on three platforms: Ubuntu 16.04 (Xenial), Mac OS X 10.11 (El Capitan), and Windows 8.1 and 10. We provide both binary packages and instructions for how to compile from source for all 3 platforms. + +Features +^^^^^^^^ + +Improvements since the Alpha 8 release: + + +* Support for node composition at compile, link, or runtime. +* A standard lifecycle for managed nodes. +* Improved support for Quality of Service tuning and tests. +* `New and updated design documents `__ +* More `tutorials ` and `examples `__ +* Bridging services to / from ROS1 (in addition to topics) + +Selected features from previous Alpha releases (for the complete list, see the `earlier release notes `\ ): + + +* C++ and Python implementations of ROS 2 client libraries including APIs for: + + * Publishing and subscribing to ROS topics + * Requesting and replying ROS services (synchronous (C++ only) and asynchronous) + * Getting and setting ROS parameters (C++ only, synchronous and asynchronous) + * Timer callbacks + * Support for interoperability between multiple DDS/RTPS implementations + * eProsima FastRTPS is our default implementation, and is included in the binary packages + * RTI Connext is supported: build from source to try it out + * We initially supported PrismTech OpenSplice but eventually decided to drop it + +* A graph API for network events +* Distributed discovery +* Realtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment) + + * Support for custom allocators + +* ROS 1 <-> ROS 2 dynamic bridge node +* Executor threading model in C++ +* Extended ``.msg`` format with new features: + + * Bounded arrays + * Default values + +Known issues: + + +* We’re tracking issues in various repositories, but the main entry point is the `ros2/ros2 issue tracker `__ +* We’d like to highlight a `known issue `__ that we are working with eProsima to fix that results in significantly degrated performance for large messages under FastRTPS. + This will be observed when running some of the demos with larger image resolutions. diff --git a/Beta2-Overview.md b/Beta2-Overview.md deleted file mode 100644 index 6d08c4d85b3..00000000000 --- a/Beta2-Overview.md +++ /dev/null @@ -1,61 +0,0 @@ -### Beta 2 (codename r2b2; July 2017) - -Welcome to the latest release of ROS 2 software! We hope that you try it out and provide feedback. - -### Supported Platforms - -We support ROS 2 Beta 2 on three platforms: Ubuntu 16.04 (Xenial), Mac OS X 10.12 (Sierra), and Windows 10. -We provide both binary packages and instructions for how to compile from source for all 3 platforms (see [install instructions](Installation.md) as well as [documentation](http://docs.ros2.org/beta2/)). - -### Features - -Improvements since the Beta 1 release: -* DDS_Security support (aka SROS2, see [sros2](https://github.com/ros2/sros2)) -* Debian packages for Ubuntu Xenial (see [Debian install instructions](Linux-Install-Debians.md)). -* Typesupport has been redesigned so that you only build a single executable and can choose one of the available RMW implementations by setting an environment variable (see [documentation](Working-with-multiple-RMW-implementations.md)). -* Namespace support for nodes and topics (see [design article](http://design.ros2.org/articles/topic_and_service_names.html), see known issues below). -* A set of command-line tools using the extensible `ros2` command (see [tutorial](Introspection-with-command-line-tools.md)). -* A set of macros for logging messages in C / C++ (see API docs of [rcutils](http://docs.ros2.org/beta2/api/rcutils/index.html)). - -New demo application: -* [Turtlebot 2 demos](https://github.com/ros2/turtlebot2_demo) using the following repositories that have been (partially) converted to ROS 2 (Linux only): - * [ros_astra_camera](https://github.com/ros2/ros_astra_camera.git) - * [depthimage_to_laserscan](https://github.com/ros2/depthimage_to_laserscan.git) - * [pcl_conversions](https://github.com/ros2/pcl_conversions.git) - * [cartographer](https://github.com/ros2/cartographer.git) - * [cartographer_ros](https://github.com/ros2/cartographer_ros.git) - * [ceres-solver](https://github.com/ros2/ceres-solver.git) - * [navigation](https://github.com/ros2/navigation.git) - * [teleop_twist_keyboard](https://github.com/ros2/teleop_twist_keyboard.git) - * [joystick_drivers](https://github.com/ros2/joystick_drivers.git) - * [teleop_twist_joy](https://github.com/ros2/teleop_twist_joy.git) -* [Dummy_robot demo](dummy-robot-demo.md): - * [robot_model](https://github.com/ros2/robot_model) - * [robot_state_publisher](https://github.com/ros2/robot_state_publisher) - -Selected features from previous Alpha/Beta releases (for the complete list, see the [earlier release notes](Releases.md)): -* C++ and Python implementations of ROS 2 client libraries including APIs for: - * Publishing and subscribing to ROS topics - * Requesting and replying ROS services (synchronous (C++ only) and asynchronous) - * Getting and setting ROS parameters (C++ only, synchronous and asynchronous) - * Timer callbacks -* Support for interoperability between multiple DDS/RTPS implementations - * eProsima FastRTPS is our default implementation, and is included in the binary packages - * RTI Connext is supported: build from source to try it out - * We initially supported PrismTech OpenSplice but support for it is currently on hold -* A graph API for network events -* Distributed discovery -* Realtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment) - * Support for custom allocators -* ROS 1 <-> ROS 2 dynamic bridge node -* Executor threading model (C++ only) -* Component model to compose nodes at compile / link / runtime -* Managed component using a standard lifecycle -* Extended `.msg` format with new features: - * Bounded arrays - * Default values - -Known issues: -* We’re tracking issues in various repositories, but the main entry point is the [ros2/ros2 issue tracker](https://github.com/ros2/ros2/issues) -* We’d like to highlight a [known issue](https://github.com/ros2/rmw_connext/issues/234) that we are looking into which doesn't allow two topics with the same base name but different namespaces to have a different type when using `rmw_connext_cpp`. -* Services with long responses are not working with Fast-RTPS. The fix, while not being part of beta2, is available upstream so you can work around this issue by building from source using Fast-RTPS master branch. \ No newline at end of file diff --git a/Beta2-Overview.rst b/Beta2-Overview.rst new file mode 100644 index 00000000000..74862fc890d --- /dev/null +++ b/Beta2-Overview.rst @@ -0,0 +1,83 @@ + +Beta 2 (codename r2b2; July 2017) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Welcome to the latest release of ROS 2 software! We hope that you try it out and provide feedback. + +Supported Platforms +^^^^^^^^^^^^^^^^^^^ + +We support ROS 2 Beta 2 on three platforms: Ubuntu 16.04 (Xenial), Mac OS X 10.12 (Sierra), and Windows 10. +We provide both binary packages and instructions for how to compile from source for all 3 platforms (see `install instructions ` as well as `documentation `__\ ). + +Features +^^^^^^^^ + +Improvements since the Beta 1 release: + + +* DDS_Security support (aka SROS2, see `sros2 `__\ ) +* Debian packages for Ubuntu Xenial (see `Debian install instructions `\ ). +* Typesupport has been redesigned so that you only build a single executable and can choose one of the available RMW implementations by setting an environment variable (see `documentation `\ ). +* Namespace support for nodes and topics (see `design article `__\ , see known issues below). +* A set of command-line tools using the extensible ``ros2`` command (see `tutorial `\ ). +* A set of macros for logging messages in C / C++ (see API docs of `rcutils `__\ ). + +New demo application: + + +* `Turtlebot 2 demos `__ using the following repositories that have been (partially) converted to ROS 2 (Linux only): + + * `ros_astra_camera `__ + * `depthimage_to_laserscan `__ + * `pcl_conversions `__ + * `cartographer `__ + * `cartographer_ros `__ + * `ceres-solver `__ + * `navigation `__ + * `teleop_twist_keyboard `__ + * `joystick_drivers `__ + * `teleop_twist_joy `__ + +* `Dummy_robot demo `\ : + + * `robot_model `__ + * `robot_state_publisher `__ + +Selected features from previous Alpha/Beta releases (for the complete list, see the `earlier release notes `\ ): + + +* C++ and Python implementations of ROS 2 client libraries including APIs for: + + * Publishing and subscribing to ROS topics + * Requesting and replying ROS services (synchronous (C++ only) and asynchronous) + * Getting and setting ROS parameters (C++ only, synchronous and asynchronous) + * Timer callbacks + +* Support for interoperability between multiple DDS/RTPS implementations + + * eProsima FastRTPS is our default implementation, and is included in the binary packages + * RTI Connext is supported: build from source to try it out + * We initially supported PrismTech OpenSplice but support for it is currently on hold + +* A graph API for network events +* Distributed discovery +* Realtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment) + + * Support for custom allocators + +* ROS 1 <-> ROS 2 dynamic bridge node +* Executor threading model (C++ only) +* Component model to compose nodes at compile / link / runtime +* Managed component using a standard lifecycle +* Extended ``.msg`` format with new features: + + * Bounded arrays + * Default values + +Known issues: + + +* We’re tracking issues in various repositories, but the main entry point is the `ros2/ros2 issue tracker `__ +* We’d like to highlight a `known issue `__ that we are looking into which doesn't allow two topics with the same base name but different namespaces to have a different type when using ``rmw_connext_cpp``. +* Services with long responses are not working with Fast-RTPS. The fix, while not being part of beta2, is available upstream so you can work around this issue by building from source using Fast-RTPS master branch. diff --git a/Beta3-Overview.md b/Beta3-Overview.rst similarity index 51% rename from Beta3-Overview.md rename to Beta3-Overview.rst index 9e6a064852b..caad9fb7720 100644 --- a/Beta3-Overview.md +++ b/Beta3-Overview.rst @@ -1,52 +1,72 @@ -### Beta 3 (codename r2b3; September 2017) + +Beta 3 (codename r2b3; September 2017) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Welcome to the latest release of ROS 2 software! We hope that you try it out and provide feedback. -### Supported Platforms +Supported Platforms +^^^^^^^^^^^^^^^^^^^ We support ROS 2 Beta 3 on three platforms: Ubuntu 16.04 (Xenial), Mac OS X 10.12 (Sierra), and Windows 10. -We provide both binary packages and instructions for how to compile from source for all 3 platforms (see [install instructions](Installation.md) as well as [documentation](http://docs.ros2.org/beta3/)). +We provide both binary packages and instructions for how to compile from source for all 3 platforms (see `install instructions ` as well as `documentation `__\ ). -### Features +Features +^^^^^^^^ Improvements since the Beta 2 release: -- Execution model in Python, many fixes to memory management in Python C extension -- Experimental rewrite of [ros_control](https://github.com/ros2/ros2_control) -- Exposure of DDS implementation-specific symbols to users (for FastRTPS and Connext) (see [example](https://github.com/ros2/demos/blob/6363be2efe2fea799d92bc22a66e776b2ca9c5d0/demo_nodes_cpp_native/src/talker.cpp)) -- Logging [API](https://github.com/ros2/rclpy/blob/1ef2924ef8e154c0553edf0fdba4840b08b728f8/rclpy/rclpy/logging.py) in Python -- Fixed several memory leaks and race conditions in various packages -- Readded support for OpenSplice (on Linux and Windows atm) provided by PrismTech -- Use bloom (without patches) to make ROS 2 releases + + +* Execution model in Python, many fixes to memory management in Python C extension +* Experimental rewrite of `ros_control `__ +* Exposure of DDS implementation-specific symbols to users (for FastRTPS and Connext) (see `example `__\ ) +* Logging `API `__ in Python +* Fixed several memory leaks and race conditions in various packages +* Readded support for OpenSplice (on Linux and Windows atm) provided by PrismTech +* Use bloom (without patches) to make ROS 2 releases New demo application: -* [HSR demo](https://github.com/ruffsl/hsr_demo) + + +* `HSR demo `_ + * Remote control a HSR robot using a ROS 2 joystick controller - * Running the `ros1_bridge` in a Docker container on the HSR (since the robot is running ROS 1 on Ubuntu Trusty) - * Run a ROS 2 development version of [rviz](https://github.com/ros2/rviz) to visualize sensor data from the robot etc. (see [video](https://vimeo.com/237016358)) + * Running the ``ros1_bridge`` in a Docker container on the HSR (since the robot is running ROS 1 on Ubuntu Trusty) + * Run a ROS 2 development version of `rviz `__ to visualize sensor data from the robot etc. (see `video `__\ ) + +Selected features from previous Alpha/Beta releases (for the complete list, see the `earlier release notes `\ ): + -Selected features from previous Alpha/Beta releases (for the complete list, see the [earlier release notes](Releases.md)): * C++ and Python implementations of ROS 2 client libraries including APIs for: + * Publishing and subscribing to ROS topics * Requesting and replying ROS services (synchronous (C++ only) and asynchronous) * Getting and setting ROS parameters (C++ only, synchronous and asynchronous) * Timer callbacks + * Support for interoperability between multiple DDS/RTPS implementations + * eProsima FastRTPS is our default implementation, and is included in the binary packages * RTI Connext is supported: build from source to try it out * PrismTech OpenSplice: see limitations below + * A graph API for network events * Distributed discovery * Realtime safe code paths for publish and subscribe with compatible DDS implementation (only Connext at the moment) + * Support for custom allocators + * ROS 1 <-> ROS 2 dynamic bridge node * Executor threading model (C++ and Python) * Component model to compose nodes at compile / link / runtime * Managed component using a standard lifecycle -* Extended `.msg` format with new features: +* Extended ``.msg`` format with new features: + * Bounded arrays * Default values Known issues: -* On Windows Python launch files might hang when trying to abort using `Ctrl-C` (see [issue](https://github.com/ros2/launch/issues/64)). In order to continue using the shell which is blocked by the hanging command you might want to end the hanging Python process using the process monitor. -* OpenSplice support is currently not available for MacOS. Also [access to native handles](https://github.com/ros2/rmw_opensplice/issues/182) is not yet implemented. -* Using Connext it is currently not allowed for two topics with the same base name but different namespaces to have a different type (see [issue](https://github.com/ros2/rmw_connext/issues/234)).. + + +* On Windows Python launch files might hang when trying to abort using ``Ctrl-C`` (see `issue `__\ ). In order to continue using the shell which is blocked by the hanging command you might want to end the hanging Python process using the process monitor. +* OpenSplice support is currently not available for MacOS. Also `access to native handles `__ is not yet implemented. +* Using Connext it is currently not allowed for two topics with the same base name but different namespaces to have a different type (see `issue `__\ ).. diff --git a/Build-Cop-and-Build-Farmer-Guide.md b/Build-Cop-and-Build-Farmer-Guide.md deleted file mode 100644 index 35275d8feb1..00000000000 --- a/Build-Cop-and-Build-Farmer-Guide.md +++ /dev/null @@ -1,216 +0,0 @@ -# Build Cop and Build Farmer Guide - -This page covers two rotating developer roles we have on the ROS 2 team, the build cop and the build farmer. -These two roles are related, but subtly different. - -The build cop is responsible for monitoring our [Continuous Integration (CI) server](http://ci.ros2.org/) to make sure our ["nightly" jobs](http://ci.ros2.org/view/nightly/) and ["packaging" jobs](http://ci.ros2.org/view/packaging/) to not accumulate new regressions. -This allows us to build on relatively stable ["ci" (or "manual") jobs](http://ci.ros2.org/) when checking to see if a new feature or bug fix introduces any new regressions. - -The build farmer, on the other hand, is responsible for ensuring that [the machines that run all of our CI jobs](http://ci.ros2.org/computer/) are up, running, and up-to-date, so that they are available for other developers to check their pull requests. - -These two jobs have so far been the same person for periods of about two weeks, but they are separated here so that they could be different people in the future and to make a distinction between the roles and responsibilities. - -This document is meant mostly for ROS 2 team developers, but it might be useful for others too. - -## On-boarding - -If you are becoming the next build cop or build farmer you should: - -- Make sure you are subscribed to and have the "deliver every email" option turned on for this mailing list: - - https://groups.google.com/forum/#!forum/ros2-buildfarm -- Make sure you are "watching" this GitHub repository: - - https://github.com/ros2/build_cop -- Talk with the previous build cop or build farmer about on-going issues -- Update the description of the main view on Jenkins to the current date and your name: - - http://ci.ros2.org/ - -## Retirement - -If you are finishing your stint as either build cop or build farmer you should: - -- Unsubscribe or switch to "digest" for this mailing list: - - https://groups.google.com/forum/#!forum/ros2-buildfarm -- "Unwatch" this GitHub repository: - - https://github.com/ros2/build_cop -- Summarize the on-going issues for the next build cop or build farmer to which you are handing off - -## Build Cop - -This section assumes that you have reviewed the [ROS 2 on boarding document](ROS-2-On-boarding-Guide.md). - -### Mission - -The goal of the build cop is to keep the jobs "green" (succeeding without test failures or warnings) on the buildfarm and to report any regression to the appropriate person. -This will reduce the overhead of several people looking at, or investigating, the same build failures. -This will also allow the other people on the team not to receive nightly email for the failing and/or unstable builds. - -### Build Cop Tasks - -Every morning the build cop should go through all the nightly jobs and packaging jobs and act on new failing or unstable jobs. -The "ci" jobs, which are started manually by developers, are not the responsibility of the build cop unless all "ci" are failing, which would indicate something was merged to the default branches which is broken. -How to classify and deal with new failures is described in the next section. - -Additionally, the build cop should strive to keep track of existing issues which are either preexisting or cannot be resolved with a day or so. -Issues are tracked on this repository which only the build cop must be "watching" (getting GitHub notifications), though anyone interested can follow it too: - -https://github.com/ros2/build_cop/issues - -The above repository is also used to track Build Farmer issues. -It is meant to be a way for the build cop or build farmer to track long running items for handing off to the next person and so they can "mention" individuals on particular issues without the whole team getting notified of every issue. - -#### Types of Failures - -Each failure can be categorized into one of a few classifications: - -- Node failure: - - failures which appear to be due to a machine configuration and not a code change - - pass it on to the build farmer -- Trivial failure: - - Linter failure - - New warnings -- Critical failure: - - Breaking builds on the "default" branch - - Regression (existing tests which were passing are now failing) - - New tests that are failing (never were passing) -- Important failure: - - New feature which is not fully covered by tests - - Increase flakiness (new flaky tests or made existing flaky tests more flaky) - -#### New Failure Actions - -In each case different actions should be taken by the build cop: - -- Trivial failure should be fixed by the Build Cop right away - - Pushed on a branch - - Tested on CI - - Merged to the default branch - - Add a comment to the PR introducing the failure referencing the fixing commit -- Critical failures: - - Failure should be reported on the PR introducing it by tagging the submitter and the reviewer that +1’d it. - - Submitter of the PR has to act on it during the next half day by either: - - Reverting the change and ticketing the problem / comment on the PR the reason it’s been reverted - - Submit a patch to fix the failure -- Important failures: - - Failure should be reported on the PR introducing it by tagging the submitter + the reviewer the +1’d it. - - Submitter has to either: - - Address it the same week - - Add it to the next sprint - -#### Tips - -- You can search for PRs merged between two dates with, e.g.: - - https://github.com/search?utf8=%E2%9C%93&q=user%3Aament+user%3Aros2+merged%3A%222017-04-17T22%3A00%3A00-08%3A00+..+2017-04-18T23%3A30%3A00-08%3A00%22&type=Issues - - (note that FastRTPS and other external repos won’t appear) -- To get the exact list of code that changed, generate a diff between the output of `vcs export --exact` between two builds. - - This is particularly useful for external repos such as FastRTPS where old commits may get pushed to the master branch overnight, and are difficult to spot in the GitHub UI. -- Times displayed at the top of jenkins jobs are in UTC. You can convert the times with e.g.: - - https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=when+it's+9:25:12+PM+UTC+time+pst -- If linter failures occur overnight it is usually because of a new version of a linter. - - Create a diff of the last `pip freeze` output of two builds to see which versions changed. - - If it's a regression in a dependency you can pin the older version temporarily, see [this PR for an example](https://github.com/ros2/ci/pull/129). - -## Build Farmer - -This section assumes that you have reviewed the [ROS 2 on boarding document](ROS-2-On-boarding-Guide.md). - -### Mission - -The mission of the build farmer is to keep the [build farm](http://ci.ros2.org/) in a healthy, up-to-date state. -Ideally all Jenkins nodes will have the same/latest version of every package. -This will require monitoring and patching up any node when things come up. - -### Build Farmer Tasks - -- Monitor the buildfarm (using the https://groups.google.com/forum/#!forum/ros2-buildfarm mailing list for email notifications) -- Take failing nodes off-line with descriptive message about the issue and investigate the failure ASAP. - - Taking a node off-line: - - log in ci.ros2.org - - click on the node in the left column of Jenkins UI (e.g. osx_slave_mini1) - - click on "Mark this node temporary off-line" button (top right corner) - - Investigate the failure (see section below) -- Report error and fixing attempt using the [Build Farmer Reporting Form](https://docs.google.com/a/osrfoundation.org/forms/d/e/1FAIpQLSc40KMD8hb1-JMkUBRF6o17CAt1mtEQY8w4O8PN8rFq0hEkxQ/viewform) - - If the same problem and action is taken on multiple nodes, select all the relevant nodes in the form before submitting it -- If fixing attempt failed: - - Keep the node off-line on the farm - - Update the reason for node being off-line - - Put the status and error message in the status sheet of the [logbook](https://docs.google.com/a/osrfoundation.org/spreadsheets/d/1_7pv1Kb2MDhk4jzpS1cjTVJ6wgdVIN3ZxaN-QdZ7XuM/edit?usp=sharing) - - Allocate time in the next few days to dive in the problem -- If you rescue a previously off-line node: - - Update the status sheet of the logbook by: - - Removing the error message in the status column - - Update the date next to it -- Once investigation is finished: clean the machine: close all your windows, stash or remove any local changes - - Rationale - - Anybody logging into the machine need to know that no one is working on it - - If the machine reboots the machine needs to be in an operational state without local changes -- Making sure install instructions are up to date -- Use the existing logbook to put together an FAQ or best practice to rescue nodes - -### How to Investigate a Failing Node - -If the node failed to build: look at the console output of the failing build; - -- Click on the link of the failing job received by email or go to ci.ros2.org and click on the number (e.g. #2345) next to the failing job(red icon). -- Click on Console Output in the left column -- Look for the reason of the failure -- If the failure is not due to a machine configuration, relay to the build cop - -If you need to access a machine: - -- See this spreadsheet (private) for credentials for all the different Jenkins Nodes: - - https://docs.google.com/a/osrfoundation.org/spreadsheets/d/1OSwqbE3qPF8v3HSMr8JOaJ6r4QOiQFk6pwgaudXVE-4/edit?usp=sharing -- For machines hosted at OSRF, you'll need to be on the OSRF network or have a VPN connection. -- For machines which require ask on ros@osrfoundation.org for your public keys to be added. -- The Packet.net nodes (with "packet" in the name): - - Can be managed by logging in at https://packet.net with / - - This will change after we set up a team account to manage servers. - - Can be accessed with Tully’s or Brian’s ssh key. - - This will change after we set up a team account to manage servers. - -### Troubleshooting - -If a node goes off-line: - -- For machines with VNC, you should try that first because many failures can be due to pop-up windows or required updates -- If you don’t have any pop-ups and relaunching the jenkins client doesn’t fix it, then you'll have to start troubleshooting. -- Looking at configuration difference between the nodes may be useful (java version, pip freeze, etc.) -- For Linux nodes that have gone off-line (e.g. because of a reboot), they can be reconnected through the Jenkins web interface of that node - -Other tips: - ----- - -The environment variables on Windows machines are output at the beginning of Jenkins jobs (search for `==> set`). -If you are modifying environment variables on Windows nodes, you may need to restart the machine before the changes are reflected in the jobs. -This is due to the Jenkins slave session caching the environment variables to some degree. - ----- - -On the Windows machines, the Jenkins slave program runs as a service as the System account. -For this user, the "home" directory seems to be `C:\Windows\system32\config\systemprofile`. -You can "become" the system user to debug stuff by downloading `pxexec`: - -https://technet.microsoft.com/en-us/sysinternals/pxexec - -Then you extract the zip, then open a command-prompt as administrator, and then run: `psexec -i -s cmd.exe` - -This is all pieced together from a couple of pages here: - -http://blog.thomasvandoren.com/jenkins-windows-slave-with-git.html - -and here: - -https://answers.atlassian.com/questions/128324/where-is-the-home-directory-for-the-system-user - ----- - -Every so often the router reboots. The mac machines usually don’t reconnect to Jenkins properly. Just manually reconnect them. - -### Resources - -- [How to setup the Jenkins master](CI-Server-Setup.md). -- [How to setup Linux Jenkins nodes](Set-up-a-new-Linux-CI-node.md). -- [How to setup a macOS Jenkins node](Set-up-a-new-macOS-CI-node.md). - - (old instructions) https://docs.google.com/a/osrfoundation.org/document/d/1J_8O7Q7eiixC-axyjP_bVpZSALyhn67Y1K_-SAw5eh0/edit?usp=sharing -- [How to setup a Windows Jenkins node](Set-up-a-new-Windows-CI-node.md). - - (old instructions) https://docs.google.com/a/osrfoundation.org/document/d/1SmmWa7MVnwjmMw9XJF33-fsa0dtkYj2AeEXBa8BCsYs/edit?usp=sharing diff --git a/Build-Cop-and-Build-Farmer-Guide.rst b/Build-Cop-and-Build-Farmer-Guide.rst new file mode 100644 index 00000000000..2d7e9f25364 --- /dev/null +++ b/Build-Cop-and-Build-Farmer-Guide.rst @@ -0,0 +1,298 @@ +.. role:: raw-html-m2r(raw) + :format: html + + +Build Cop and Build Farmer Guide +================================ + +This page covers two rotating developer roles we have on the ROS 2 team, the build cop and the build farmer. +These two roles are related, but subtly different. + +The build cop is responsible for monitoring our `Continuous Integration (CI) server `__ to make sure our `"nightly" jobs `__ and `"packaging" jobs `__ to not accumulate new regressions. +This allows us to build on relatively stable `"ci" (or "manual") jobs `__ when checking to see if a new feature or bug fix introduces any new regressions. + +The build farmer, on the other hand, is responsible for ensuring that `the machines that run all of our CI jobs `__ are up, running, and up-to-date, so that they are available for other developers to check their pull requests. + +These two jobs have so far been the same person for periods of about two weeks, but they are separated here so that they could be different people in the future and to make a distinction between the roles and responsibilities. + +This document is meant mostly for ROS 2 team developers, but it might be useful for others too. + +On-boarding +----------- + +If you are becoming the next build cop or build farmer you should: + + +* Make sure you are subscribed to and have the "deliver every email" option turned on for this mailing list: + + * https://groups.google.com/forum/#!forum/ros2-buildfarm + +* Make sure you are "watching" this GitHub repository: + + * https://github.com/ros2/build_cop + +* Talk with the previous build cop or build farmer about on-going issues +* Update the description of the main view on Jenkins to the current date and your name: + + * http://ci.ros2.org/ + +Retirement +---------- + +If you are finishing your stint as either build cop or build farmer you should: + + +* Unsubscribe or switch to "digest" for this mailing list: + + * https://groups.google.com/forum/#!forum/ros2-buildfarm + +* "Unwatch" this GitHub repository: + + * https://github.com/ros2/build_cop + +* Summarize the on-going issues for the next build cop or build farmer to which you are handing off + +Build Cop +--------- + +This section assumes that you have reviewed the `ROS 2 on boarding document `. + +Mission +^^^^^^^ + +The goal of the build cop is to keep the jobs "green" (succeeding without test failures or warnings) on the buildfarm and to report any regression to the appropriate person. +This will reduce the overhead of several people looking at, or investigating, the same build failures. +This will also allow the other people on the team not to receive nightly email for the failing and/or unstable builds. + +Build Cop Tasks +^^^^^^^^^^^^^^^ + +Every morning the build cop should go through all the nightly jobs and packaging jobs and act on new failing or unstable jobs. +The "ci" jobs, which are started manually by developers, are not the responsibility of the build cop unless all "ci" are failing, which would indicate something was merged to the default branches which is broken. +How to classify and deal with new failures is described in the next section. + +Additionally, the build cop should strive to keep track of existing issues which are either preexisting or cannot be resolved with a day or so. +Issues are tracked on this repository which only the build cop must be "watching" (getting GitHub notifications), though anyone interested can follow it too: + +https://github.com/ros2/build_cop/issues + +The above repository is also used to track Build Farmer issues. +It is meant to be a way for the build cop or build farmer to track long running items for handing off to the next person and so they can "mention" individuals on particular issues without the whole team getting notified of every issue. + +Types of Failures +~~~~~~~~~~~~~~~~~ + +Each failure can be categorized into one of a few classifications: + + +* Node failure: + + * failures which appear to be due to a machine configuration and not a code change + * pass it on to the build farmer + +* Trivial failure: + + * Linter failure + * New warnings + +* Critical failure: + + * Breaking builds on the "default" branch + * Regression (existing tests which were passing are now failing) + * New tests that are failing (never were passing) + +* Important failure: + + * New feature which is not fully covered by tests + * Increase flakiness (new flaky tests or made existing flaky tests more flaky) + +New Failure Actions +~~~~~~~~~~~~~~~~~~~ + +In each case different actions should be taken by the build cop: + + +* Trivial failure should be fixed by the Build Cop right away + + * Pushed on a branch + * Tested on CI + * Merged to the default branch + * Add a comment to the PR introducing the failure referencing the fixing commit + +* Critical failures: + + * Failure should be reported on the PR introducing it by tagging the submitter and the reviewer that +1’d it. + * Submitter of the PR has to act on it during the next half day by either: + + * Reverting the change and ticketing the problem / comment on the PR the reason it’s been reverted + * Submit a patch to fix the failure + +* Important failures: + + * Failure should be reported on the PR introducing it by tagging the submitter + the reviewer the +1’d it. + * Submitter has to either: + + * Address it the same week + * Add it to the next sprint + +Tips +~~~~ + + +* You can search for PRs merged between two dates with, e.g.: + + * https://github.com/search?utf8=%E2%9C%93&q=user%3Aament+user%3Aros2+merged%3A%222017-04-17T22%3A00%3A00-08%3A00+..+2017-04-18T23%3A30%3A00-08%3A00%22&type=Issues + * (note that FastRTPS and other external repos won’t appear) + +* To get the exact list of code that changed, generate a diff between the output of ``vcs export --exact`` between two builds. + + * This is particularly useful for external repos such as FastRTPS where old commits may get pushed to the master branch overnight, and are difficult to spot in the GitHub UI. + +* Times displayed at the top of jenkins jobs are in UTC. You can convert the times with e.g.: + + * https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=when+it's+9:25:12+PM+UTC+time+pst + +* If linter failures occur overnight it is usually because of a new version of a linter. + + * Create a diff of the last ``pip freeze`` output of two builds to see which versions changed. + * If it's a regression in a dependency you can pin the older version temporarily, see `this PR for an example `__. + +Build Farmer +------------ + +This section assumes that you have reviewed the `ROS 2 on boarding document `. + +Mission +^^^^^^^ + +The mission of the build farmer is to keep the `build farm `__ in a healthy, up-to-date state. +Ideally all Jenkins nodes will have the same/latest version of every package. +This will require monitoring and patching up any node when things come up. + +Build Farmer Tasks +^^^^^^^^^^^^^^^^^^ + + +* Monitor the buildfarm (using the https://groups.google.com/forum/#!forum/ros2-buildfarm mailing list for email notifications) +* Take failing nodes off-line with descriptive message about the issue and investigate the failure ASAP. + + * Taking a node off-line: + + * log in ci.ros2.org + * click on the node in the left column of Jenkins UI (e.g. osx_slave_mini1) + * click on "Mark this node temporary off-line" button (top right corner) + + * Investigate the failure (see section below) + +* Report error and fixing attempt using the `Build Farmer Reporting Form `__ + + * If the same problem and action is taken on multiple nodes, select all the relevant nodes in the form before submitting it + +* If fixing attempt failed: + + * Keep the node off-line on the farm + * Update the reason for node being off-line + * Put the status and error message in the status sheet of the `logbook `__ + * Allocate time in the next few days to dive in the problem + +* If you rescue a previously off-line node: + + * Update the status sheet of the logbook by: + + * Removing the error message in the status column + * Update the date next to it + +* Once investigation is finished: clean the machine: close all your windows, stash or remove any local changes + + * Rationale + + * Anybody logging into the machine need to know that no one is working on it + * If the machine reboots the machine needs to be in an operational state without local changes + +* Making sure install instructions are up to date +* Use the existing logbook to put together an FAQ or best practice to rescue nodes + +How to Investigate a Failing Node +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If the node failed to build: look at the console output of the failing build; + + +* Click on the link of the failing job received by email or go to ci.ros2.org and click on the number (e.g. #2345) next to the failing job(red icon). +* Click on Console Output in the left column +* Look for the reason of the failure +* If the failure is not due to a machine configuration, relay to the build cop + +If you need to access a machine: + + +* See this spreadsheet (private) for credentials for all the different Jenkins Nodes: + + * https://docs.google.com/a/osrfoundation.org/spreadsheets/d/1OSwqbE3qPF8v3HSMr8JOaJ6r4QOiQFk6pwgaudXVE-4/edit?usp=sharing + +* For machines hosted at OSRF, you'll need to be on the OSRF network or have a VPN connection. +* For machines which require :raw-html-m2r:`` ask on ros@osrfoundation.org for your public keys to be added. +* The Packet.net nodes (with "packet" in the name): + + * Can be managed by logging in at https://packet.net with /\ :raw-html-m2r:`` + + * This will change after we set up a team account to manage servers. + + * Can be accessed with Tully’s or Brian’s ssh key. + + * This will change after we set up a team account to manage servers. + +Troubleshooting +^^^^^^^^^^^^^^^ + +If a node goes off-line: + + +* For machines with VNC, you should try that first because many failures can be due to pop-up windows or required updates +* If you don’t have any pop-ups and relaunching the jenkins client doesn’t fix it, then you'll have to start troubleshooting. +* Looking at configuration difference between the nodes may be useful (java version, pip freeze, etc.) +* For Linux nodes that have gone off-line (e.g. because of a reboot), they can be reconnected through the Jenkins web interface of that node + +Other tips: + +---- + +The environment variables on Windows machines are output at the beginning of Jenkins jobs (search for ``==> set``\ ). +If you are modifying environment variables on Windows nodes, you may need to restart the machine before the changes are reflected in the jobs. +This is due to the Jenkins slave session caching the environment variables to some degree. + +---- + +On the Windows machines, the Jenkins slave program runs as a service as the System account. +For this user, the "home" directory seems to be ``C:\Windows\system32\config\systemprofile``. +You can "become" the system user to debug stuff by downloading ``pxexec``\ : + +https://technet.microsoft.com/en-us/sysinternals/pxexec + +Then you extract the zip, then open a command-prompt as administrator, and then run: ``psexec -i -s cmd.exe`` + +This is all pieced together from a couple of pages here: + +http://blog.thomasvandoren.com/jenkins-windows-slave-with-git.html + +and here: + +https://answers.atlassian.com/questions/128324/where-is-the-home-directory-for-the-system-user + +---- + +Every so often the router reboots. The mac machines usually don’t reconnect to Jenkins properly. Just manually reconnect them. + +Resources +^^^^^^^^^ + + +* `How to setup the Jenkins master `. +* `How to setup Linux Jenkins nodes `. +* `How to setup a macOS Jenkins node `. + + * (old instructions) https://docs.google.com/a/osrfoundation.org/document/d/1J_8O7Q7eiixC-axyjP_bVpZSALyhn67Y1K_-SAw5eh0/edit?usp=sharing + +* `How to setup a Windows Jenkins node `. + + * (old instructions) https://docs.google.com/a/osrfoundation.org/document/d/1SmmWa7MVnwjmMw9XJF33-fsa0dtkYj2AeEXBa8BCsYs/edit?usp=sharing diff --git a/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.md b/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.md deleted file mode 100644 index e8def25fe30..00000000000 --- a/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.md +++ /dev/null @@ -1,128 +0,0 @@ -**Note: Some people have reported issues about this tutorial. If the steps work for you please leave a comment on https://github.com/ros2/ros2/issues/495 . If they don't then please comment with the first step that didn't work.** - -This tutorial is based on a clean ubuntu-16.04.2 install and eclipse oxygen with egit. It uses RTI Connext as middleware for Realtime performance. The [original Install page](Linux-Development-Setup.md) is perhaps more up-to-date, so check it for info. - -Install: -``` -sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' -sudo apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116 -``` - -``` -sudo apt update -sudo apt install git wget build-essential cppcheck cmake libopencv-dev python-empy python3-dev python3-empy python3-nose python3-pip python3-pyparsing python3-setuptools python3-vcstool python3-yaml libtinyxml-dev libeigen3-dev clang-format pydocstyle pyflakes python3-coverage python3-mock python3-pep8 uncrustify libasio-dev libtinyxml2-dev libcurl4-openssl-dev libqt5core5a libqt5gui5 libqt5opengl5 libqt5widgets5 libxaw7-dev libgles2-mesa-dev libglu1-mesa-dev qtbase5-dev -``` -Then install -``` -sudo pip3 install argcomplete flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes pytest pytest-cov pytest-runner -``` - - -Create a eclipse workspace named ros2_ws. (The name is not needed to be ros2_ws) -![eclipse-1](https://i.imgur.com/sdN8cab.png) - -Inside this eclipse-workspace we create a C++ Project. With this option we have a indexer for code-completion. -![eclipse-1](https://i.imgur.com/TDsxpVS.png) - -We name the project ros2_ws -![eclipse-1](https://i.imgur.com/4db7JQI.png) - -We see our project and some includes. These includes dont reside in our workspace, so dont remove, they are for the indexer. -![eclipse-1](https://i.imgur.com/RsllCLW.png) - -We create a folder inside our project, named "src" -![eclipse-1](https://i.imgur.com/WUGDQvB.png) - -We see the folder in our project. This folder also exist in our workspace. -After that we go to a console and switch to directory /home/ros/ros2_ws/ros2_ws there we enter -``` -wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -vcs-import src < ros2.repos -``` -add export RTI_LICENSE_FILE=/home/ros/rti_connext_dds-5.3.1/rti_license.dat to .bashrc and source it. - - - -![eclipse-1](https://i.imgur.com/AtT6pWi.png) - -We now need a RTI license, which we get on their website. Refer to [Linux Development Setup page](Linux-Development-Setup.md). The RTI license file will be directly send per email after sign-up. - -In the email is a link to the RTI software to download. We run the .run file after chmod +x -![eclipse-1](https://i.imgur.com/daIBmJA.png) - -![eclipse-1](https://i.imgur.com/ji7Wfl6.png) - -We choose our home directory to install -![eclipse-1](https://i.imgur.com/8pE0GAX.png) - -![eclipse-1](https://i.imgur.com/tgIxhWz.png) - - -![eclipse-1](https://i.imgur.com/MwnqcLO.png) - -In the Launcher which started, we select our RTI license file and copy it global -![eclipse-1](https://i.imgur.com/0cQRX04.png) - -select in the down-left side the install-button -![eclipse-1](https://i.imgur.com/R3eXEc5.png) - -install the security package from RTI software -![eclipse-1](https://i.imgur.com/MJSELif.png) - -and the openssl package -![eclipse-1](https://i.imgur.com/4IH3Jig.png) - -Unpack the openssl-1.0.2n package and copy it to the RTI install directory. source /home/ros/rti_connext_dds-5.3.1/resource/scripts/rtisetenv_x64Linux3gcc5.4.0.bash on a console and export RMW_IMPLEMENTATION=rmw_connext_cpp. - -Close eclipse-IDE and open it from the shell we sourced all the scripts from above.We now open in Eclipse the Project->Preferences and go to Environment. - -![eclipse-1](https://i.imgur.com/lzL0vra.png) - -We enter environment variables. We can get the vars simply by opening a bash console, then we run "env > /tmp/out", then source the ROS 2 local_setup.bash, then "env > /tmp/out1" and "diff /tmp/out /tmp/out1". The output that diff is showing, is what we enter in eclipse environment vars, so that eclipse knows about e.g. the new PATH var. -![eclipse-1](https://i.imgur.com/D30l1Ps.png) - -![eclipse-1](https://i.imgur.com/ydPADre.png) - - -Then we go to Builders and click the "New" button. -![eclipse-1](https://i.imgur.com/GFZXHPb.png) - -We enter the amen.py settings -![eclipse-1](https://i.imgur.com/30mWuIF.png) - -After that we unselect CDT-Builder -![eclipse-1](https://i.imgur.com/LuwaGBa.png) - - -Then we go to C++ Build and delete the build command make, because we use ament.py (Dont know really if this is needed -as we disabled CDT-Builder before?) -![eclipse-1](https://i.imgur.com/KiXiAPP.png) - -We now can right-click and run "Build Project". - -HINT if it happens: -error: NDDSHOME set to but could neither find all optimized libraries nor all debug libraries -I deleted dir /home/ros/rti_connext_dds-5.3.1/lib/x64Linux3gcc5.4.0/5.3.1/5.3.1 with doubled libs - -![eclipse-1](https://i.imgur.com/30xv4ka.png) - -We can then open two console, source ros2_ws/install/local_setup.bash in both consoles and run talker and listener -![eclipse-1](https://i.imgur.com/5NDrDVL.png) - -We see our Project in eclipse, go to git-repositories-view and import local repo -![eclipse-1](https://i.imgur.com/e0x2dnI.png) - -We select our directory and select the repository we are interresting in seeing e.g. git-infos like author of code-line, or switching to other branches, etc. -![eclipse-1](https://i.imgur.com/RkXnmjr.png) - -After adding the git-repo to the git-repository-view, we can right-click on it and select "Import projects" -![eclipse-1](https://i.imgur.com/KxS9x66.png) - -The import source is the directory of our project -![eclipse-1](https://i.imgur.com/L4HSOEl.png) - -We see in the down-left side in the project-explorer view, that this project is beside our ros2_ws project. But they both use the same files.But one is linked with Egit and can show git-annotations, etc. the other not. So open files from the project which is linked to Egit. -![eclipse-1](https://i.imgur.com/2jBRVlV.png) - -File linked with Egit. Right-click beside the line-number in the editor and choose "Show Revision information" from the pop-up dialog, then you could see e.g. the author, and other stuff like commit message if you hover over it with the mouse. -![eclipse-1](https://i.imgur.com/TyOQFhl.png) \ No newline at end of file diff --git a/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.rst b/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.rst new file mode 100644 index 00000000000..4765ec2f6c7 --- /dev/null +++ b/Building-ROS-2-on-Linux-with-Eclipse-Oxygen.rst @@ -0,0 +1,248 @@ + +**Note: Some people have reported issues about this tutorial. If the steps work for you please leave a comment on https://github.com/ros2/ros2/issues/495 . If they don't then please comment with the first step that didn't work.** + +This tutorial is based on a clean ubuntu-16.04.2 install and eclipse oxygen with egit. It uses RTI Connext as middleware for Realtime performance. The `original Install page ` is perhaps more up-to-date, so check it for info. + +Install: + +.. code-block:: + + sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' + sudo apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116 + +.. code-block:: + + sudo apt update + sudo apt install git wget build-essential cppcheck cmake libopencv-dev python-empy python3-dev python3-empy python3-nose python3-pip python3-pyparsing python3-setuptools python3-vcstool python3-yaml libtinyxml-dev libeigen3-dev clang-format pydocstyle pyflakes python3-coverage python3-mock python3-pep8 uncrustify libasio-dev libtinyxml2-dev libcurl4-openssl-dev libqt5core5a libqt5gui5 libqt5opengl5 libqt5widgets5 libxaw7-dev libgles2-mesa-dev libglu1-mesa-dev qtbase5-dev + +Then install + +.. code-block:: + + sudo pip3 install argcomplete flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes pytest pytest-cov pytest-runner + +Create a eclipse workspace named ros2_ws. (The name is not needed to be ros2_ws) + +.. image:: https://i.imgur.com/sdN8cab.png + :target: https://i.imgur.com/sdN8cab.png + :alt: eclipse-1 + + +Inside this eclipse-workspace we create a C++ Project. With this option we have a indexer for code-completion. + +.. image:: https://i.imgur.com/TDsxpVS.png + :target: https://i.imgur.com/TDsxpVS.png + :alt: eclipse-1 + + +We name the project ros2_ws + +.. image:: https://i.imgur.com/4db7JQI.png + :target: https://i.imgur.com/4db7JQI.png + :alt: eclipse-1 + + +We see our project and some includes. These includes dont reside in our workspace, so dont remove, they are for the indexer. + +.. image:: https://i.imgur.com/RsllCLW.png + :target: https://i.imgur.com/RsllCLW.png + :alt: eclipse-1 + + +We create a folder inside our project, named "src" + +.. image:: https://i.imgur.com/WUGDQvB.png + :target: https://i.imgur.com/WUGDQvB.png + :alt: eclipse-1 + + +We see the folder in our project. This folder also exist in our workspace. +After that we go to a console and switch to directory /home/ros/ros2_ws/ros2_ws there we enter + +.. code-block:: + + wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos + vcs-import src < ros2.repos + +add export RTI_LICENSE_FILE=/home/ros/rti_connext_dds-5.3.1/rti_license.dat to .bashrc and source it. + + +.. image:: https://i.imgur.com/AtT6pWi.png + :target: https://i.imgur.com/AtT6pWi.png + :alt: eclipse-1 + + +We now need a RTI license, which we get on their website. Refer to `Linux Development Setup page `. The RTI license file will be directly send per email after sign-up. + +In the email is a link to the RTI software to download. We run the .run file after chmod +x + +.. image:: https://i.imgur.com/daIBmJA.png + :target: https://i.imgur.com/daIBmJA.png + :alt: eclipse-1 + + + +.. image:: https://i.imgur.com/ji7Wfl6.png + :target: https://i.imgur.com/ji7Wfl6.png + :alt: eclipse-1 + + +We choose our home directory to install + +.. image:: https://i.imgur.com/8pE0GAX.png + :target: https://i.imgur.com/8pE0GAX.png + :alt: eclipse-1 + + + +.. image:: https://i.imgur.com/tgIxhWz.png + :target: https://i.imgur.com/tgIxhWz.png + :alt: eclipse-1 + + + +.. image:: https://i.imgur.com/MwnqcLO.png + :target: https://i.imgur.com/MwnqcLO.png + :alt: eclipse-1 + + +In the Launcher which started, we select our RTI license file and copy it global + +.. image:: https://i.imgur.com/0cQRX04.png + :target: https://i.imgur.com/0cQRX04.png + :alt: eclipse-1 + + +select in the down-left side the install-button + +.. image:: https://i.imgur.com/R3eXEc5.png + :target: https://i.imgur.com/R3eXEc5.png + :alt: eclipse-1 + + +install the security package from RTI software + +.. image:: https://i.imgur.com/MJSELif.png + :target: https://i.imgur.com/MJSELif.png + :alt: eclipse-1 + + +and the openssl package + +.. image:: https://i.imgur.com/4IH3Jig.png + :target: https://i.imgur.com/4IH3Jig.png + :alt: eclipse-1 + + +Unpack the openssl-1.0.2n package and copy it to the RTI install directory. source /home/ros/rti_connext_dds-5.3.1/resource/scripts/rtisetenv_x64Linux3gcc5.4.0.bash on a console and export RMW_IMPLEMENTATION=rmw_connext_cpp. + +Close eclipse-IDE and open it from the shell we sourced all the scripts from above.We now open in Eclipse the Project->Preferences and go to Environment. + + +.. image:: https://i.imgur.com/lzL0vra.png + :target: https://i.imgur.com/lzL0vra.png + :alt: eclipse-1 + + +We enter environment variables. We can get the vars simply by opening a bash console, then we run "env > /tmp/out", then source the ROS 2 local_setup.bash, then "env > /tmp/out1" and "diff /tmp/out /tmp/out1". The output that diff is showing, is what we enter in eclipse environment vars, so that eclipse knows about e.g. the new PATH var. + +.. image:: https://i.imgur.com/D30l1Ps.png + :target: https://i.imgur.com/D30l1Ps.png + :alt: eclipse-1 + + + +.. image:: https://i.imgur.com/ydPADre.png + :target: https://i.imgur.com/ydPADre.png + :alt: eclipse-1 + + +Then we go to Builders and click the "New" button. + +.. image:: https://i.imgur.com/GFZXHPb.png + :target: https://i.imgur.com/GFZXHPb.png + :alt: eclipse-1 + + +We enter the amen.py settings + +.. image:: https://i.imgur.com/30mWuIF.png + :target: https://i.imgur.com/30mWuIF.png + :alt: eclipse-1 + + +After that we unselect CDT-Builder + +.. image:: https://i.imgur.com/LuwaGBa.png + :target: https://i.imgur.com/LuwaGBa.png + :alt: eclipse-1 + + +Then we go to C++ Build and delete the build command make, because we use ament.py (Dont know really if this is needed +as we disabled CDT-Builder before?) + +.. image:: https://i.imgur.com/KiXiAPP.png + :target: https://i.imgur.com/KiXiAPP.png + :alt: eclipse-1 + + +We now can right-click and run "Build Project". + +HINT if it happens: +error: NDDSHOME set to but could neither find all optimized libraries nor all debug libraries +I deleted dir /home/ros/rti_connext_dds-5.3.1/lib/x64Linux3gcc5.4.0/5.3.1/5.3.1 with doubled libs + + +.. image:: https://i.imgur.com/30xv4ka.png + :target: https://i.imgur.com/30xv4ka.png + :alt: eclipse-1 + + +We can then open two console, source ros2_ws/install/local_setup.bash in both consoles and run talker and listener + +.. image:: https://i.imgur.com/5NDrDVL.png + :target: https://i.imgur.com/5NDrDVL.png + :alt: eclipse-1 + + +We see our Project in eclipse, go to git-repositories-view and import local repo + +.. image:: https://i.imgur.com/e0x2dnI.png + :target: https://i.imgur.com/e0x2dnI.png + :alt: eclipse-1 + + +We select our directory and select the repository we are interresting in seeing e.g. git-infos like author of code-line, or switching to other branches, etc. + +.. image:: https://i.imgur.com/RkXnmjr.png + :target: https://i.imgur.com/RkXnmjr.png + :alt: eclipse-1 + + +After adding the git-repo to the git-repository-view, we can right-click on it and select "Import projects" + +.. image:: https://i.imgur.com/KxS9x66.png + :target: https://i.imgur.com/KxS9x66.png + :alt: eclipse-1 + + +The import source is the directory of our project + +.. image:: https://i.imgur.com/L4HSOEl.png + :target: https://i.imgur.com/L4HSOEl.png + :alt: eclipse-1 + + +We see in the down-left side in the project-explorer view, that this project is beside our ros2_ws project. But they both use the same files.But one is linked with Egit and can show git-annotations, etc. the other not. So open files from the project which is linked to Egit. + +.. image:: https://i.imgur.com/2jBRVlV.png + :target: https://i.imgur.com/2jBRVlV.png + :alt: eclipse-1 + + +File linked with Egit. Right-click beside the line-number in the editor and choose "Show Revision information" from the pop-up dialog, then you could see e.g. the author, and other stuff like commit message if you hover over it with the mouse. + +.. image:: https://i.imgur.com/TyOQFhl.png + :target: https://i.imgur.com/TyOQFhl.png + :alt: eclipse-1 + diff --git a/Building-Realtime-rt_preempt-kernel-for-ROS-2.md b/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst similarity index 53% rename from Building-Realtime-rt_preempt-kernel-for-ROS-2.md rename to Building-Realtime-rt_preempt-kernel-for-ROS-2.rst index 3e067a4f552..442861b2504 100644 --- a/Building-Realtime-rt_preempt-kernel-for-ROS-2.md +++ b/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst @@ -1,103 +1,130 @@ + This Tutorial begins with a clean ubuntu 16.04.2 install. Actual kernel is 4.13.0-38-generic, but we will install another one. If you are a company or rich person :) using rt_preempt, check https://wiki.linuxfoundation.org/realtime/rtl/blog#preempt-rt-history Check on https://wiki.linuxfoundation.org/realtime/start what the latest stable version is, at this time it is Latest Stable Version 4.9-rt. If we click on the link, we get the exact version, it is patch-4.9.84-rt62.patch.gz -![eclipse-1](https://i.imgur.com/bAMOzbt.png) + +.. image:: https://i.imgur.com/bAMOzbt.png + :target: https://i.imgur.com/bAMOzbt.png + :alt: eclipse-1 We create a directory in our home dir with -``` -mkdir ~/kernel -``` +.. code-block:: + + mkdir ~/kernel and switch into it with -``` -cd ~/kernel -``` + +.. code-block:: + + cd ~/kernel We can go with a browser to https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/ and see if the version is there, then download it with -``` -wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.9.84.tar.gz -``` + +.. code-block:: + + wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.9.84.tar.gz unpack it with -``` -tar -xzf linux-4.9.84.tar.gz -``` + +.. code-block:: + + tar -xzf linux-4.9.84.tar.gz rename it to the same name with postfix of the patch version -``` -mv linux-4.9.84 linux-4.9.84-rt62 -``` + +.. code-block:: + + mv linux-4.9.84 linux-4.9.84-rt62 download rt_preempt patch with -``` -wget ftp.ntu.edu.tw/linux/kernel/projects/rt/4.9/older/patch-4.9.84-rt62.patch.gz -``` +.. code-block:: + + wget ftp.ntu.edu.tw/linux/kernel/projects/rt/4.9/older/patch-4.9.84-rt62.patch.gz unpack it with -``` -gunzip patch-4.9.84-rt62.patch.gz -``` + +.. code-block:: + + gunzip patch-4.9.84-rt62.patch.gz + Then switch into the linux directory with -``` -cd linux-4.9.84-rt62/ -``` + +.. code-block:: + + cd linux-4.9.84-rt62/ + and patch the kernel with the realtime patch -``` -patch -p1 < ../patch-4.9.84-rt62.patch -``` -![eclipse-1](https://i.imgur.com/u1VFptM.png) +.. code-block:: + patch -p1 < ../patch-4.9.84-rt62.patch + + +.. image:: https://i.imgur.com/u1VFptM.png + :target: https://i.imgur.com/u1VFptM.png + :alt: eclipse-1 We simply wanna use the config of our ubuntu installation, so we use the ubuntu config with -``` -cp /boot/config-4.13.0-38-generic .config -``` + +.. code-block:: + + cp /boot/config-4.13.0-38-generic .config To enable all ubuntu-configurations, we simply use -``` -yes '' | make oldconfig -``` + +.. code-block:: + + yes '' | make oldconfig We need some tools, install them with -``` -sudo apt install libncurses5-dev build-essential libssl-dev ccache -``` + +.. code-block:: + + sudo apt install libncurses5-dev build-essential libssl-dev ccache Then we need to enable rt_preempt in the kernel. We call -``` -make menuconfig -``` + +.. code-block:: + + make menuconfig and choose under “Processor Type and Features” --- “Preemption Model” --- “Fully Preemptible kernel (RT)” -![eclipse-1](https://i.imgur.com/Jg5zX6G.png) + +.. image:: https://i.imgur.com/Jg5zX6G.png + :target: https://i.imgur.com/Jg5zX6G.png + :alt: eclipse-1 Exit menuconfig and run -``` -make -``` + +.. code-block:: + + make You could use “make -j4” if you got 4-cpu-cores to build faster. Then we need to build the kernel modules with -``` -sudo make modules_install -``` + +.. code-block:: + + sudo make modules_install Then we install the kernel to /boot and update grub with -``` -sudo make install -``` -![eclipse-1](https://i.imgur.com/Y5ihCXd.png) +.. code-block:: + + sudo make install + +.. image:: https://i.imgur.com/Y5ihCXd.png + :target: https://i.imgur.com/Y5ihCXd.png + :alt: eclipse-1 diff --git a/CI-Server-Setup.md b/CI-Server-Setup.md deleted file mode 100644 index f307b6fe741..00000000000 --- a/CI-Server-Setup.md +++ /dev/null @@ -1,206 +0,0 @@ -# Setup CI server - -## Installing - -Install the latest LTS release from http://pkg.jenkins-ci.org/debian-stable/ - -## Running on port 80 - -I used this SO answer to setup a subdomain to a port: - -http://serverfault.com/a/140161/186748 - -I had to remove the `hudson` in each of the lines that contained it. - -## Temporary rewrite for changed job name - -We renamed some of the jobs, so I added rewrite rules in Apache (`/etc/apache2/sites-enabled/ci.ros2.org.conf`): - -``` -# Temporary rewrite rule because we changed the Windows job name. -RewriteEngine On -RewriteRule ^(.*)/ros2_batch_ci_linux/(.*)$ $1/ci_linux/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_osx/(.*)$ $1/ci_osx/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows/(.*)$ $1/ci_windows_opensplice/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_opensplice/(.*)$ $1/ci_windows_opensplice/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_connext_static/(.*)$ $1/ci_windows_connext_static/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_connext_dynamic/(.*)$ $1/ci_windows_connext_dynamic/$2 [R=301,L] -RewriteRule ^(.*)/ci_windows_opensplice/(.*)$ $1/ci_windows/$2 [R=301,L] -RewriteRule ^(.*)/ci_windows_connext_static/(.*)$ $1/old_windows_connext_static/$2 [R=301,L] -RewriteRule ^(.*)/ci_windows_connext_dynamic/(.*)$ $1/old_windows_connext_dynamic/$2 [R=301,L] -RewriteRule ^(.*)/ci_windows_fastrtps/(.*)$ $1/old_windows_fastrtps/$2 [R=301,L] - -RewriteRule ^(.*)/ros2_batch_ci_linux_nightly/(.*)$ $1/nightly_linux/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_osx_nightly/(.*)$ $1/nightly_osx/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_opensplice_nightly/(.*)$ $1/nightly_windows_opensplice/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_connext_static_nightly/(.*)$ $1/nightly_windows_connext_static/$2 [R=301,L] -RewriteRule ^(.*)/ros2_batch_ci_windows_connext_dynamic_nightly/(.*)$ $1/nightly_windows_connext_dynamic/$2 [R=301,L] -RewriteRule ^(.*)/nightly_windows_opensplice/(.*)$ $1/nightly_windows/$2 [R=301,L] -RewriteRule ^(.*)/nightly_windows_connext_static/(.*)$ $1/old_night_windows_connext_static/$2 [R=301,L] -RewriteRule ^(.*)/nightly_windows_connext_dynamic/(.*)$ $1/old_night_windows_connext_dynamic/$2 [R=301,L] - -RewriteRule ^(.*)/ros2_packaging_linux/(.*)$ $1/packaging_linux/$2 [R=301,L] -RewriteRule ^(.*)/ros2_packaging_osx/(.*)$ $1/packaging_osx/$2 [R=301,L] -RewriteRule ^(.*)/ros2_packaging_windows_opensplice/(.*)$ $1/packaging_windows_opensplice/$2 [R=301,L] -RewriteRule ^(.*)/packaging_windows_opensplice/(.*)$ $1/packaging_windows/$2 [R=301,L] -``` - -## Install stuff (needed on master and slaves) - -``` -sudo apt update -sudo apt install -y git -# Your java version will vary depending on your OS: -#sudo apt install openjdk-7-jre-headless -#sudo apt install openjdk-8-jre-headless -# For ARM native servers, we need the tomcat native libs to support ssh-agent -# (https://issues.jenkins-ci.org/browse/JENKINS-30746) -#sudo apt install libtcnative-1 -# qemu and vcs are required for ARM builds -sudo apt install -y qemu-user-static -sudo bash -c 'echo "deb http://repositories.ros.org/ubuntu/testing/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' -sudo bash -c 'curl --silent http://repositories.ros.org/repos.key |sudo apt-key add -' -# Or, on aarch64: -#sudo apt install docker.io -sudo apt update -sudo apt install -y python-vcstool -curl -fsSL https://get.docker.com/ | sh -sudo adduser --disabled-password jenkins -sudo usermod -aG docker jenkins -sudo service docker start -``` - -## Adding a Linux slave to the farm -Approximately: - -* Shell into the master (`ci.ros2.org`), copy `/var/lib/jenkins/.ssh/id_rsa.pub` and paste it into `/home/jenkins/.ssh/authorized_keys` on the new machine. -* Copy config from the `linux 2` machine, rename and otherwise modify as needed (e.g., change the IP/host). -* Copy `/etc/ssh/ssh_host_rsa_key.pub` from the new machine and add it as an entry in `/var/lib/jenkins/.ssh/known_hosts` (with the new machine's IP) on the master, then re-hash that file on the master: `ssh-keygen -H`. - -## Configuring Jenkins - -First I updated all the preinstalled plugins. - -### Authentication - -Then I setup authentication with the `github-oauth` plugin. -I just installed it and followed their setup instructions: - -https://wiki.jenkins-ci.org/display/JENKINS/Github+OAuth+Plugin - -I created an application entry on the ros2 GitHub organization: - -https://github.com/organizations/ros2/settings/applications/215300 - -I also tuned the permissions in `Manage Jenkins->Configure Global Security`. - -### Plugins - -Next I installed all of these plugins: - -- `ansicolor` -- `description-setter` -- `github` (other git* plugins are deps of the `github-oauth` plugin) -- `greenballs` -- `groovy` -- `parameterized-trigger` -- `PrioritySorter` -- `jobrequeue` -- `ssh-agent` -- `warnings` -- `xunit` - -### Adding an ssh key - -Jenkins needs a valid ssh key in order to pull from some of our private repositories, for example to get the rti deb files. - -So I created an ssh key for the jenkins user on the webserver: - -``` -sudo su jenkins -cd -mkdir .ssh -ssh-keygen -t rsa -``` - -Then I added to the jenkins credentials as an "From the jenkins master ~/.ssh" with the user id of `ros2-buildfarm`. - -I added this key to a "machine" GitHub account that I created for this farm and I added that user, `ros2-buildfarm`, to the `ros2`, `ament`, and `osrf` organizations. - -## Creating Jobs - -I cloned the `ros2/ci` repository to the default branch (`master`): - -``` -git clone https://github.com/ros2/ci.git -``` - -Then I cloned the `ros_buildfarm` repository: - -``` -git clone https://github.com/ros-infrastructure/ros_buildfarm.git -``` - -I also install the `jenkinsapi` and `EmPy` Python packages: - -``` -sudo apt install python3-pip -sudo -H python3 -m pip install -U pip -sudo -H python3 -m pip install jenkinsapi EmPy -``` - -Then I setup auth: - -``` -mkdir -p ~/.buildfarm -vim ~/.buildfarm/jenkins.ini -``` - -Put this in the `jenkins.ini` file: - -``` -[http://ci.ros2.org] -username=wjwwood -password= -``` - -Now, you should first login with GitHub on Jenkins if you haven't already. -Then put your github username in and for the application token, browse to the configuration of your user on Jenkins: - -http://ci.ros2.org/user/wjwwood/configure - -In those settings there should be a field called API Token. -Copy that field for your password. - -Now I can create the jobs: - -``` -$ PYTHONPATH=`pwd`/../ros_buildfarm ./create_jenkins_job.py -u http://ci.ros2.org -Connecting to Jenkins 'http://ci.ros2.org' -Connected to Jenkins version '1.617' -Creating job 'ros2_batch_ci_windows' -The Jenkins master does not require a crumb -Creating job 'ros2_batch_ci_osx' -Creating job 'ros2_batch_ci_linux' -Creating job 'ros2_batch_ci_launcher' -``` - -### Tuning Auto-generated Jobs - -The final step is to fine tune the jobs. -For each job you'll want to check the ssh key being used for the git clone (only on Linux) and the ssh-agent. -It should be set to the ssh key setup in the previous steps for the jenkins user. - -I also updated the slaves which the jobs will run on to make sure they matched the names of the slaves I added for Linux, OS X and Windows. - -## Disk space - -Over time docker images and particularly containers will pile up. -To clean up use: - -``` -docker rm $(docker ps -a -q) -docker rmi $(docker images -q -f dangling=true) -``` - -from https://www.calazan.com/docker-cleanup-commands/ diff --git a/CI-Server-Setup.rst b/CI-Server-Setup.rst new file mode 100644 index 00000000000..aa9df2fab4a --- /dev/null +++ b/CI-Server-Setup.rst @@ -0,0 +1,223 @@ + +Setup CI server +=============== + +Installing +---------- + +Install the latest LTS release from http://pkg.jenkins-ci.org/debian-stable/ + +Running on port 80 +------------------ + +I used this SO answer to setup a subdomain to a port: + +http://serverfault.com/a/140161/186748 + +I had to remove the ``hudson`` in each of the lines that contained it. + +Temporary rewrite for changed job name +-------------------------------------- + +We renamed some of the jobs, so I added rewrite rules in Apache (\ ``/etc/apache2/sites-enabled/ci.ros2.org.conf``\ ): + +.. code-block:: + + # Temporary rewrite rule because we changed the Windows job name. + RewriteEngine On + RewriteRule ^(.*)/ros2_batch_ci_linux/(.*)$ $1/ci_linux/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_osx/(.*)$ $1/ci_osx/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows/(.*)$ $1/ci_windows_opensplice/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_opensplice/(.*)$ $1/ci_windows_opensplice/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_connext_static/(.*)$ $1/ci_windows_connext_static/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_connext_dynamic/(.*)$ $1/ci_windows_connext_dynamic/$2 [R=301,L] + RewriteRule ^(.*)/ci_windows_opensplice/(.*)$ $1/ci_windows/$2 [R=301,L] + RewriteRule ^(.*)/ci_windows_connext_static/(.*)$ $1/old_windows_connext_static/$2 [R=301,L] + RewriteRule ^(.*)/ci_windows_connext_dynamic/(.*)$ $1/old_windows_connext_dynamic/$2 [R=301,L] + RewriteRule ^(.*)/ci_windows_fastrtps/(.*)$ $1/old_windows_fastrtps/$2 [R=301,L] + + RewriteRule ^(.*)/ros2_batch_ci_linux_nightly/(.*)$ $1/nightly_linux/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_osx_nightly/(.*)$ $1/nightly_osx/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_opensplice_nightly/(.*)$ $1/nightly_windows_opensplice/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_connext_static_nightly/(.*)$ $1/nightly_windows_connext_static/$2 [R=301,L] + RewriteRule ^(.*)/ros2_batch_ci_windows_connext_dynamic_nightly/(.*)$ $1/nightly_windows_connext_dynamic/$2 [R=301,L] + RewriteRule ^(.*)/nightly_windows_opensplice/(.*)$ $1/nightly_windows/$2 [R=301,L] + RewriteRule ^(.*)/nightly_windows_connext_static/(.*)$ $1/old_night_windows_connext_static/$2 [R=301,L] + RewriteRule ^(.*)/nightly_windows_connext_dynamic/(.*)$ $1/old_night_windows_connext_dynamic/$2 [R=301,L] + + RewriteRule ^(.*)/ros2_packaging_linux/(.*)$ $1/packaging_linux/$2 [R=301,L] + RewriteRule ^(.*)/ros2_packaging_osx/(.*)$ $1/packaging_osx/$2 [R=301,L] + RewriteRule ^(.*)/ros2_packaging_windows_opensplice/(.*)$ $1/packaging_windows_opensplice/$2 [R=301,L] + RewriteRule ^(.*)/packaging_windows_opensplice/(.*)$ $1/packaging_windows/$2 [R=301,L] + +Install stuff (needed on master and slaves) +------------------------------------------- + +.. code-block:: + + sudo apt update + sudo apt install -y git + # Your java version will vary depending on your OS: + #sudo apt install openjdk-7-jre-headless + #sudo apt install openjdk-8-jre-headless + # For ARM native servers, we need the tomcat native libs to support ssh-agent + # (https://issues.jenkins-ci.org/browse/JENKINS-30746) + #sudo apt install libtcnative-1 + # qemu and vcs are required for ARM builds + sudo apt install -y qemu-user-static + sudo bash -c 'echo "deb http://repositories.ros.org/ubuntu/testing/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' + sudo bash -c 'curl --silent http://repositories.ros.org/repos.key |sudo apt-key add -' + # Or, on aarch64: + #sudo apt install docker.io + sudo apt update + sudo apt install -y python-vcstool + curl -fsSL https://get.docker.com/ | sh + sudo adduser --disabled-password jenkins + sudo usermod -aG docker jenkins + sudo service docker start + +Adding a Linux slave to the farm +-------------------------------- + +Approximately: + + +* Shell into the master (\ ``ci.ros2.org``\ ), copy ``/var/lib/jenkins/.ssh/id_rsa.pub`` and paste it into ``/home/jenkins/.ssh/authorized_keys`` on the new machine. +* Copy config from the ``linux 2`` machine, rename and otherwise modify as needed (e.g., change the IP/host). +* Copy ``/etc/ssh/ssh_host_rsa_key.pub`` from the new machine and add it as an entry in ``/var/lib/jenkins/.ssh/known_hosts`` (with the new machine's IP) on the master, then re-hash that file on the master: ``ssh-keygen -H``. + +Configuring Jenkins +------------------- + +First I updated all the preinstalled plugins. + +Authentication +^^^^^^^^^^^^^^ + +Then I setup authentication with the ``github-oauth`` plugin. +I just installed it and followed their setup instructions: + +https://wiki.jenkins-ci.org/display/JENKINS/Github+OAuth+Plugin + +I created an application entry on the ros2 GitHub organization: + +https://github.com/organizations/ros2/settings/applications/215300 + +I also tuned the permissions in ``Manage Jenkins->Configure Global Security``. + +Plugins +^^^^^^^ + +Next I installed all of these plugins: + + +* ``ansicolor`` +* ``description-setter`` +* ``github`` (other git* plugins are deps of the ``github-oauth`` plugin) +* ``greenballs`` +* ``groovy`` +* ``parameterized-trigger`` +* ``PrioritySorter`` +* ``jobrequeue`` +* ``ssh-agent`` +* ``warnings`` +* ``xunit`` + +Adding an ssh key +^^^^^^^^^^^^^^^^^ + +Jenkins needs a valid ssh key in order to pull from some of our private repositories, for example to get the rti deb files. + +So I created an ssh key for the jenkins user on the webserver: + +.. code-block:: + + sudo su jenkins + cd + mkdir .ssh + ssh-keygen -t rsa + +Then I added to the jenkins credentials as an "From the jenkins master ~/.ssh" with the user id of ``ros2-buildfarm``. + +I added this key to a "machine" GitHub account that I created for this farm and I added that user, ``ros2-buildfarm``\ , to the ``ros2``\ , ``ament``\ , and ``osrf`` organizations. + +Creating Jobs +------------- + +I cloned the ``ros2/ci`` repository to the default branch (\ ``master``\ ): + +.. code-block:: + + git clone https://github.com/ros2/ci.git + +Then I cloned the ``ros_buildfarm`` repository: + +.. code-block:: + + git clone https://github.com/ros-infrastructure/ros_buildfarm.git + +I also install the ``jenkinsapi`` and ``EmPy`` Python packages: + +.. code-block:: + + sudo apt install python3-pip + sudo -H python3 -m pip install -U pip + sudo -H python3 -m pip install jenkinsapi EmPy + +Then I setup auth: + +.. code-block:: + + mkdir -p ~/.buildfarm + vim ~/.buildfarm/jenkins.ini + +Put this in the ``jenkins.ini`` file: + +.. code-block:: + + [http://ci.ros2.org] + username=wjwwood + password= + +Now, you should first login with GitHub on Jenkins if you haven't already. +Then put your github username in and for the application token, browse to the configuration of your user on Jenkins: + +http://ci.ros2.org/user/wjwwood/configure + +In those settings there should be a field called API Token. +Copy that field for your password. + +Now I can create the jobs: + +.. code-block:: + + $ PYTHONPATH=`pwd`/../ros_buildfarm ./create_jenkins_job.py -u http://ci.ros2.org + Connecting to Jenkins 'http://ci.ros2.org' + Connected to Jenkins version '1.617' + Creating job 'ros2_batch_ci_windows' + The Jenkins master does not require a crumb + Creating job 'ros2_batch_ci_osx' + Creating job 'ros2_batch_ci_linux' + Creating job 'ros2_batch_ci_launcher' + +Tuning Auto-generated Jobs +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The final step is to fine tune the jobs. +For each job you'll want to check the ssh key being used for the git clone (only on Linux) and the ssh-agent. +It should be set to the ssh key setup in the previous steps for the jenkins user. + +I also updated the slaves which the jobs will run on to make sure they matched the names of the slaves I added for Linux, OS X and Windows. + +Disk space +---------- + +Over time docker images and particularly containers will pile up. +To clean up use: + +.. code-block:: + + docker rm $(docker ps -a -q) + docker rmi $(docker images -q -f dangling=true) + +from https://www.calazan.com/docker-cleanup-commands/ diff --git a/Colcon-Tutorial.md b/Colcon-Tutorial.md deleted file mode 100644 index 8a78018c870..00000000000 --- a/Colcon-Tutorial.md +++ /dev/null @@ -1,207 +0,0 @@ -# Overview - -This will provide you with a quick summary of how to get up and running using `colcon` and a ROS workspace. -It will be a practical tutorial and is not designed to replace the core documentation. - -ROS 2 releases before Bouncy were using `ament_tools` described in the [ament tutorial](Ament-Tutorial.md). - -## Background - -colcon is an iteration on the ROS build tools catkin_make, catkin_make_isolated, catkin_tools and ament_tools. -For more information on the design of colcon see [this document](http://design.ros2.org/articles/build_tool.html). - -The source code can be found in the [colcon GitHub organization](https://github.com/colcon). - -## Prerequisites - -## Development Environment - -Make sure that you have setup your development environment according to the building-from-source [instructions](Installation.md). - -## Basics - -A ROS workspace is a directory with a particular structure. -Commonly there is a `src` subdirectory. -Inside that subdirectory is where the source code of ROS packages will be located. -Typically the directory starts otherwise empty. - -colcon does out of source builds. -By default it will create the following directories as peers of the `src` directory: - -- The `build` directory will be where intermediate files are stored. -For each package a subfolder will be created in which e.g. CMake is being invoked. -- The `install` directory is where each package will be installed to. -By default each package will be installed into a separate subdirectory. -- The `log` directory contains various logging information about each colcon invocation. - -NB: Compared to catkin there is no `devel` directory. - -## Create directory structure - -To make the basic structure in the directory `~/ros2_ws`: - -```bash -mkdir -p ~/ros2_ws/src -cd ~/ros2_ws -``` - -This is the directory structure of `~/ros2_ws` that you can expect at this point: - -``` -. -└── src - -1 directory, 0 files -``` - -## Add some sources - -To start off we need to setup an underlay workspace without any of ROS 2 installed. - -```bash -wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -vcs import ~/ros2_ws/src < ros2.repos -``` - -This is the directory structure of `~/ros2_ws` that you can expect after adding sources (note the exact structure and number of directories/files may change over time): - -``` -. -├── ros2.repos -└── src - ├── ament - │   ├── ament_cmake - │   ├── ament_index - | ... - │   ├── osrf_pycommon - │   └── uncrustify - ├── eProsima - │   ├── Fast-CDR - │   └── Fast-RTPS - ├── ros - │   ├── class_loader - │   └── console_bridge - └── ros2 - ├── ament_cmake_ros - ├── common_interfaces - ├── demos - ... - ├── urdfdom - ├── urdfdom_headers - └── vision_opencv - -51 directories, 1 file -``` - -## Run the build - -Since build types such as `ament_cmake` do not support the concept of the `devel` space and require the package to be installed, colcon supports the option `--symlink-install`. -This allows the installed files to be changed by changing the files in the `source` space (e.g. Python files or other not compiled resourced) for faster iteration. - -```bash -colcon build --symlink-install -``` - -## Run the tests - -To run the tests you just built, run the following: - -```bash -colcon test -``` - -## Source the environment - -When colcon has completed building successfully the output will be in the `install` directory. -To use the executables and libraries you need to e.g. add the `install/bin` directory to your path. -colcon will have generated bash/bat files in the `install` directory to help setup the environment. -These files will both add the required elements to your path and library paths as well as provide any exported bash or shell commands exported by packages. - -```bash -. install/local_setup.bash -``` - -NB: This is slightly different than catkin. -The `local_setup.*` file is slightly different than the `setup.*` file in that it will only apply settings from the current workspace. -When using more than one workspace you will still source the `setup.*` files to get the environment including all parent workspaces. - -## Try a demo - -With the environment sourced you can now run executables built by colcon. - -```bash -ros2 run demo_nodes_cpp listener & -ros2 run demo_nodes_cpp talker -``` - -And you will see the numbers incrementing. - -Lets take down the nodes and try creating our own workspace overlay. - -```bash -^-C -kill %1 -``` - -## Develop your own package - -colcon uses the same `package.xml` specification as defined for catkin in [REP 149](http://www.ros.org/reps/rep-0149.html). - -You can create your own package inside the `src` directory however it is recommended to use an overlay when you are going to iterate only on a few packages. - -## Create an overlay - -Let's make a new overlay directory `~/ros2_overlay_ws`. - -```bash -mkdir -p ~/ros2_overlay_ws/src -cd ~/ros2_overlay_ws/src -``` - -And to get started we'll overlay the [ros2/examples repository](https://github.com/ros2/examples): - -```bash -# If you know that you're using the latest branch of all -# repositories in the underlay, you can also get the latest -# version of the ros2/examples repository, with this command: -# git clone https://github.com/ros2/examples.git -# Otherwise, clone a copy from the underlay source code: -git clone ~/ros2_ws/src/ros2/examples -``` - -And build the overlay, but let's build with debug so we can make sure to get debug symbols: - -```bash -cd ~/ros2_overlay_ws -colcon build --cmake-args -DCMAKE_BUILD_TYPE=Debug -``` - -This overlay has not yet been setup to be on top of the existing underlay so you'll still find that `which talker` currently refers to the one from the underlay. - -If you source `~/ros2_overlay_ws/install/local_setup.bash` it will change to refer to talker in the overlay. - -If you are returning with a new terminal to your development and want to pick up developing on your overlay you can simply source `~/ros2_overlay_ws/install/setup.bash` which will source all parent workspaces environments automatically. - -## Create your own package - -You can create your own package. -The equivalent of `catkin_create_package` is available as `ros2 pkg create`. - -colcon supports multiple build types. -The recommended build types are `ament_cmake` and `ament_python`. -Also supported are pure `cmake` packages. - -An example of an `ament_python` build is the [`ament_index_python` package](https://github.com/ament/ament_index/tree/master/ament_index_python), where the setup.py is the primary entry point for building. - -A package such as [`demo_nodes_cpp`](https://github.com/ros2/demos/tree/master/demo_nodes_cpp) uses the `ament_cmake` build type, and uses CMake as the build tool. - -## Tips - -- If you do not want to build a specific package place an empty file named `COLCON_IGNORE` in the directory and it will not be indexed. - -- If you want to avoid configuring and building tests in CMake packages you can pass: `--cmake-args -DBUILD_TESTING=0`. - -- If you want to run a single particular test from a package: -``` -colcon test --packages-select YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG -``` \ No newline at end of file diff --git a/Colcon-Tutorial.rst b/Colcon-Tutorial.rst new file mode 100644 index 00000000000..dd833ec26eb --- /dev/null +++ b/Colcon-Tutorial.rst @@ -0,0 +1,229 @@ + +Overview +======== + +This will provide you with a quick summary of how to get up and running using ``colcon`` and a ROS workspace. +It will be a practical tutorial and is not designed to replace the core documentation. + +ROS 2 releases before Bouncy were using ``ament_tools`` described in the `ament tutorial `. + +Background +---------- + +colcon is an iteration on the ROS build tools catkin_make, catkin_make_isolated, catkin_tools and ament_tools. +For more information on the design of colcon see `this document `__. + +The source code can be found in the `colcon GitHub organization `__. + +Prerequisites +------------- + +Development Environment +----------------------- + +Make sure that you have setup your development environment according to the building-from-source `instructions `. + +Basics +------ + +A ROS workspace is a directory with a particular structure. +Commonly there is a ``src`` subdirectory. +Inside that subdirectory is where the source code of ROS packages will be located. +Typically the directory starts otherwise empty. + +colcon does out of source builds. +By default it will create the following directories as peers of the ``src`` directory: + + +* The ``build`` directory will be where intermediate files are stored. + For each package a subfolder will be created in which e.g. CMake is being invoked. +* The ``install`` directory is where each package will be installed to. + By default each package will be installed into a separate subdirectory. +* The ``log`` directory contains various logging information about each colcon invocation. + +NB: Compared to catkin there is no ``devel`` directory. + +Create directory structure +-------------------------- + +To make the basic structure in the directory ``~/ros2_ws``\ : + +.. code-block:: bash + + mkdir -p ~/ros2_ws/src + cd ~/ros2_ws + +This is the directory structure of ``~/ros2_ws`` that you can expect at this point: + +.. code-block:: + + . + └── src + + 1 directory, 0 files + +Add some sources +---------------- + +To start off we need to setup an underlay workspace without any of ROS 2 installed. + +.. code-block:: bash + + wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos + vcs import ~/ros2_ws/src < ros2.repos + +This is the directory structure of ``~/ros2_ws`` that you can expect after adding sources (note the exact structure and number of directories/files may change over time): + +.. code-block:: + + . + ├── ros2.repos + └── src + ├── ament + │   ├── ament_cmake + │   ├── ament_index + | ... + │   ├── osrf_pycommon + │   └── uncrustify + ├── eProsima + │   ├── Fast-CDR + │   └── Fast-RTPS + ├── ros + │   ├── class_loader + │   └── console_bridge + └── ros2 + ├── ament_cmake_ros + ├── common_interfaces + ├── demos + ... + ├── urdfdom + ├── urdfdom_headers + └── vision_opencv + + 51 directories, 1 file + +Run the build +------------- + +Since build types such as ``ament_cmake`` do not support the concept of the ``devel`` space and require the package to be installed, colcon supports the option ``--symlink-install``. +This allows the installed files to be changed by changing the files in the ``source`` space (e.g. Python files or other not compiled resourced) for faster iteration. + +.. code-block:: bash + + colcon build --symlink-install + +Run the tests +------------- + +To run the tests you just built, run the following: + +.. code-block:: bash + + colcon test + +Source the environment +---------------------- + +When colcon has completed building successfully the output will be in the ``install`` directory. +To use the executables and libraries you need to e.g. add the ``install/bin`` directory to your path. +colcon will have generated bash/bat files in the ``install`` directory to help setup the environment. +These files will both add the required elements to your path and library paths as well as provide any exported bash or shell commands exported by packages. + +.. code-block:: bash + + . install/local_setup.bash + +NB: This is slightly different than catkin. +The ``local_setup.*`` file is slightly different than the ``setup.*`` file in that it will only apply settings from the current workspace. +When using more than one workspace you will still source the ``setup.*`` files to get the environment including all parent workspaces. + +Try a demo +---------- + +With the environment sourced you can now run executables built by colcon. + +.. code-block:: bash + + ros2 run demo_nodes_cpp listener & + ros2 run demo_nodes_cpp talker + +And you will see the numbers incrementing. + +Lets take down the nodes and try creating our own workspace overlay. + +.. code-block:: bash + + ^-C + kill %1 + +Develop your own package +------------------------ + +colcon uses the same ``package.xml`` specification as defined for catkin in `REP 149 `__. + +You can create your own package inside the ``src`` directory however it is recommended to use an overlay when you are going to iterate only on a few packages. + +Create an overlay +----------------- + +Let's make a new overlay directory ``~/ros2_overlay_ws``. + +.. code-block:: bash + + mkdir -p ~/ros2_overlay_ws/src + cd ~/ros2_overlay_ws/src + +And to get started we'll overlay the `ros2/examples repository `__\ : + +.. code-block:: bash + + # If you know that you're using the latest branch of all + # repositories in the underlay, you can also get the latest + # version of the ros2/examples repository, with this command: + # git clone https://github.com/ros2/examples.git + # Otherwise, clone a copy from the underlay source code: + git clone ~/ros2_ws/src/ros2/examples + +And build the overlay, but let's build with debug so we can make sure to get debug symbols: + +.. code-block:: bash + + cd ~/ros2_overlay_ws + colcon build --cmake-args -DCMAKE_BUILD_TYPE=Debug + +This overlay has not yet been setup to be on top of the existing underlay so you'll still find that ``which talker`` currently refers to the one from the underlay. + +If you source ``~/ros2_overlay_ws/install/local_setup.bash`` it will change to refer to talker in the overlay. + +If you are returning with a new terminal to your development and want to pick up developing on your overlay you can simply source ``~/ros2_overlay_ws/install/setup.bash`` which will source all parent workspaces environments automatically. + +Create your own package +----------------------- + +You can create your own package. +The equivalent of ``catkin_create_package`` is available as ``ros2 pkg create``. + +colcon supports multiple build types. +The recommended build types are ``ament_cmake`` and ``ament_python``. +Also supported are pure ``cmake`` packages. + +An example of an ``ament_python`` build is the `\ ``ament_index_python`` package `__\ , where the setup.py is the primary entry point for building. + +A package such as `\ ``demo_nodes_cpp`` `__ uses the ``ament_cmake`` build type, and uses CMake as the build tool. + +Tips +---- + + +* + If you do not want to build a specific package place an empty file named ``COLCON_IGNORE`` in the directory and it will not be indexed. + +* + If you want to avoid configuring and building tests in CMake packages you can pass: ``--cmake-args -DBUILD_TESTING=0``. + +* + If you want to run a single particular test from a package: + + .. code-block:: + + colcon test --packages-select YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG diff --git a/Composition.md b/Composition.md deleted file mode 100644 index 8ef20bc33b0..00000000000 --- a/Composition.md +++ /dev/null @@ -1,118 +0,0 @@ -# Composing multiple nodes in a single process - -## ROS 1 - Nodes vs. Nodelets - -In ROS 1 you can write your code either as a [ROS node](http://wiki.ros.org/Nodes) or as a [ROS nodelet](http://wiki.ros.org/nodelet). -ROS 1 nodes are being compiled into executables. -ROS 1 nodelets on the other hand are being compiled into a shared library which is then being loaded at runtime by a container process. - -## ROS 2 - Unified API - -In ROS 2 the recommended way of writing your code is that of a nodelet - we call it a `Component`. -This enables to easily add common concepts to existing code, like a [life cycle](http://design.ros2.org/articles/node_lifecycle.html). -The biggest drawback of different APIs is being avoided in ROS 2 - both approaches can use the same API in ROS 2. - -> It will still be possible to use the node-like style of "writing your own main" but for the common case it is not recommended. - -By making the process layout a deploy-time decision the user can choose between: - -* running multiple nodes in separate processes with the benefits of process/fault isolation as well as easier debugging of individual nodes and -* running multiple nodes in a single process with the lower overhead and optionally more efficient communication (see [Intra-Process-Communication]). - -The vision is that a future version of `ros2 launch` will support making these different deployments easily configurable. - -## Writing a Component - -Since a component is only built into a shared library it doesn't have a `main` function (see [Talker source code](https://github.com/ros2/demos/blob/master/composition/src/talker_component.cpp)). -A component subclasses from `rclcpp::Node`. -Since it is not in control of the thread it shouldn't perform any long running or even blocking tasks in its constructor. -Instead it can use timers to get periodic notification. -Additionally it can create publishers, subscribers, servers, and clients. - -An important aspect of making such a class a component is that the class registers itself using the package `class_loader` (see last line in the source code). -This makes the component discoverable when its library is being loaded into a running process - it acts as kind of an entry point. - -## Using components - -The [composition](https://github.com/ros2/demos/tree/master/composition) package contains a couple of different approaches how to use components. -The two most common ones are: - -1. You start a generic container process ([1](https://github.com/ros2/demos/blob/master/composition/src/api_composition.cpp)) and call the ROS service [load_node](https://github.com/ros2/demos/blob/master/composition/srv/LoadNode.srv) offered by the container. - The ROS service will then load the component specified by the passed package name and library name and start executing it within the running process. - Instead of calling the ROS service programmatically you can also use a [command line tool](https://github.com/ros2/demos/blob/master/composition/src/api_composition_cli.cpp) to invoke the ROS service with the passed command line arguments -2. You create a [custom executable](https://github.com/ros2/demos/blob/master/composition/src/manual_composition.cpp) containing multiple nodes which are known at compile time. - This approach requires that each component has a header file (which is not strictly needed for the first case). - -## Run the demos - -The executables from the [composition](https://github.com/ros2/demos/tree/master/composition) packages can be run with the following commands: - -### Run-time composition using ROS services (1.) with a publisher and subscriber - -In the first shell: - - ros2 run composition api_composition - -In the second shell (see [talker](https://github.com/ros2/demos/blob/master/composition/src/talker_component.cpp) source code): - - ros2 run composition api_composition_cli composition composition::Talker - -Now the first shell should show a message that the component was loaded as well as repeated message for publishing a message. - -Another command in the second shell (see [listener](https://github.com/ros2/demos/blob/master/composition/src/listener_component.cpp) source code): - - ros2 run composition api_composition_cli composition composition::Listener - -Now the first shell should show repeated output for each received message. - -> The demo uses hardcoded topic names and therefore you can't run `api_composition` twice. -> But in general it would be possible to run to separate container processes and load the talker and listener into separate ones and they would still communicate with each other. - -### Run-time composition using ROS services (1.) with a server and client - -The example with a server and a client is very similar. - -In the first shell: - - ros2 run composition api_composition - -In the second shell (see [server](https://github.com/ros2/demos/blob/master/composition/src/server_component.cpp) and [client](https://github.com/ros2/demos/blob/master/composition/src/client_component.cpp) source code): - - ros2 run composition api_composition_cli composition composition::Server - ros2 run composition api_composition_cli composition composition::Client - -In this case the client sends a request to the server, the server processes the request and replies with a response, and the client prints the received response. - -### Compile-time composition using ROS services (2.) - -This demos shows that the same shared libraries can be reused to compile a single executable running multiple components. -The executable contains all four components from above: talker and listener as well as server and client. - -In the shell call (see [source code](https://github.com/ros2/demos/blob/master/composition/src/manual_composition.cpp)): - - ros2 run composition manual_composition - -This should show repeated messages from both pairs, the talker and the listener as well as the server and the client. - -### Run-time composition using dlopen - -This demo presents an alternative to 1. by creating a generic container process and pass it explicitly the libraries to load without using ROS interfaces. -The process will open each library and create one instance of each "rclcpp::Node" class in the library [source code](https://github.com/ros2/demos/blob/master/composition/src/dlopen_composition.cpp)). - -**Linux** In the shell call: - - ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so - -**OSX** In the shell call: - - ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.dylib `ros2 pkg prefix composition`/lib/liblistener_component.dylib - -**Windows** In cmd.exe call - - ros2 pkg prefix composition - -to get the path to where composition is installed. Then call - - ros2 run composition dlopen_composition \bin\talker_component.dll \bin\listener_component.dll - -Now the shell should show repeated output for each sent and received message. diff --git a/Composition.rst b/Composition.rst new file mode 100644 index 00000000000..064f1c5baef --- /dev/null +++ b/Composition.rst @@ -0,0 +1,167 @@ + +Composing multiple nodes in a single process +============================================ + +ROS 1 - Nodes vs. Nodelets +-------------------------- + +In ROS 1 you can write your code either as a `ROS node `__ or as a `ROS nodelet `__. +ROS 1 nodes are being compiled into executables. +ROS 1 nodelets on the other hand are being compiled into a shared library which is then being loaded at runtime by a container process. + +ROS 2 - Unified API +------------------- + +In ROS 2 the recommended way of writing your code is that of a nodelet - we call it a ``Component``. +This enables to easily add common concepts to existing code, like a `life cycle `__. +The biggest drawback of different APIs is being avoided in ROS 2 - both approaches can use the same API in ROS 2. + +.. + + It will still be possible to use the node-like style of "writing your own main" but for the common case it is not recommended. + + +By making the process layout a deploy-time decision the user can choose between: + + +* running multiple nodes in separate processes with the benefits of process/fault isolation as well as easier debugging of individual nodes and +* running multiple nodes in a single process with the lower overhead and optionally more efficient communication (see [Intra-Process-Communication]). + +The vision is that a future version of ``ros2 launch`` will support making these different deployments easily configurable. + +Writing a Component +------------------- + +Since a component is only built into a shared library it doesn't have a ``main`` function (see `Talker source code `__\ ). +A component subclasses from ``rclcpp::Node``. +Since it is not in control of the thread it shouldn't perform any long running or even blocking tasks in its constructor. +Instead it can use timers to get periodic notification. +Additionally it can create publishers, subscribers, servers, and clients. + +An important aspect of making such a class a component is that the class registers itself using the package ``class_loader`` (see last line in the source code). +This makes the component discoverable when its library is being loaded into a running process - it acts as kind of an entry point. + +Using components +---------------- + +The `composition `__ package contains a couple of different approaches how to use components. +The two most common ones are: + + +#. You start a generic container process (\ `1 `__\ ) and call the ROS service `load_node `__ offered by the container. + The ROS service will then load the component specified by the passed package name and library name and start executing it within the running process. + Instead of calling the ROS service programmatically you can also use a `command line tool `__ to invoke the ROS service with the passed command line arguments +#. You create a `custom executable `__ containing multiple nodes which are known at compile time. + This approach requires that each component has a header file (which is not strictly needed for the first case). + +Run the demos +------------- + +The executables from the `composition `__ packages can be run with the following commands: + +Run-time composition using ROS services (1.) with a publisher and subscriber +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In the first shell: + +.. code-block:: + + ros2 run composition api_composition + + +In the second shell (see `talker `__ source code): + +.. code-block:: + + ros2 run composition api_composition_cli composition composition::Talker + + +Now the first shell should show a message that the component was loaded as well as repeated message for publishing a message. + +Another command in the second shell (see `listener `__ source code): + +.. code-block:: + + ros2 run composition api_composition_cli composition composition::Listener + + +Now the first shell should show repeated output for each received message. + +.. + + The demo uses hardcoded topic names and therefore you can't run ``api_composition`` twice. + But in general it would be possible to run to separate container processes and load the talker and listener into separate ones and they would still communicate with each other. + + +Run-time composition using ROS services (1.) with a server and client +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The example with a server and a client is very similar. + +In the first shell: + +.. code-block:: + + ros2 run composition api_composition + + +In the second shell (see `server `__ and `client `__ source code): + +.. code-block:: + + ros2 run composition api_composition_cli composition composition::Server + ros2 run composition api_composition_cli composition composition::Client + + +In this case the client sends a request to the server, the server processes the request and replies with a response, and the client prints the received response. + +Compile-time composition using ROS services (2.) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This demos shows that the same shared libraries can be reused to compile a single executable running multiple components. +The executable contains all four components from above: talker and listener as well as server and client. + +In the shell call (see `source code `__\ ): + +.. code-block:: + + ros2 run composition manual_composition + + +This should show repeated messages from both pairs, the talker and the listener as well as the server and the client. + +Run-time composition using dlopen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This demo presents an alternative to 1. by creating a generic container process and pass it explicitly the libraries to load without using ROS interfaces. +The process will open each library and create one instance of each "rclcpp::Node" class in the library `source code `__\ ). + +**Linux** In the shell call: + +.. code-block:: + + ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so + + +**OSX** In the shell call: + +.. code-block:: + + ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.dylib `ros2 pkg prefix composition`/lib/liblistener_component.dylib + + +**Windows** In cmd.exe call + +.. code-block:: + + ros2 pkg prefix composition + + +to get the path to where composition is installed. Then call + +.. code-block:: + + ros2 run composition dlopen_composition \bin\talker_component.dll \bin\listener_component.dll + + +Now the shell should show repeated output for each sent and received message. diff --git a/Contact.md b/Contact.md deleted file mode 100644 index 0a414d4fd8a..00000000000 --- a/Contact.md +++ /dev/null @@ -1,31 +0,0 @@ -# Contact us - - -If you try out ROS 2 and have feedback or questions, please get in touch with us. - - -## General/design discussion -Discussions about ROS 2 development and plans are happening on the [“Next Generation ROS” Discourse category](http://discourse.ros.org/c/ng-ros) (previously on the [sig-ng-ros (Special Interest Group on Next-Generation ROS) mailing list](https://groups.google.com/forum/?fromgroups#!forum/ros-sig-ng-ros)). -Join us there and participate in the conversation. - -If you'd like to contact us privately (e.g., if your question contains information sensitive to your organization or project), you can email us directly at `ros@osrfoundation.org`. - -## Troubleshooting -If you need help with troubleshooting your system, please first check [ROS Answers](https://answers.ros.org) to see if others have come across similar issues, otherwise ask a new questions on ROS Answers making sure to include at least the `ros2` tag and the rosdistro version you are running, e.g. `ardent`. - -## Opening issues -If you identify bugs, you can open an issue to notify the ROS team. -Before opening an issue, check if other users have reported similar issues by searching across the ros2 and ament Github organizations: [example search query](https://github.com/search?type=Issues&q=user%3Aros2+user%3Aament+my+error+output). - -If it has not been reported, feel free to open an issue in the appropriate repository tracker. -If it's not clear which tracker to use for a particular issue, file it in the [ros2/ros2 repository](https://github.com/ros2/ros2/issues) and we'll have a look at it. -When filing an issue, please make sure to: - - -* Include enough information for another person to understand the issue. -* Include information about the exact platform, software, versions, and environment relevant to the problem. This includes how you installed the software (from binaries or from source) and which ROS middleware/DDS vendor you are using (if you know it). -* In case of a bug consider providing a [short, self contained, correct (compilable), example](http://sscce.org/). - - -Pull requests are welcome for any of [the ros2 repositories](https://github.com/ros2) to suggest specific code changes! -See [Contributing](Contributing.md) for more details on how to contribute. diff --git a/Contact.rst b/Contact.rst new file mode 100644 index 00000000000..886db0a4a6b --- /dev/null +++ b/Contact.rst @@ -0,0 +1,36 @@ + +Contact us +========== + +If you try out ROS 2 and have feedback or questions, please get in touch with us. + +General/design discussion +------------------------- + +Discussions about ROS 2 development and plans are happening on the `“Next Generation ROS” Discourse category `__ (previously on the `sig-ng-ros (Special Interest Group on Next-Generation ROS) mailing list `__\ ). +Join us there and participate in the conversation. + +If you'd like to contact us privately (e.g., if your question contains information sensitive to your organization or project), you can email us directly at ``ros@osrfoundation.org``. + +Troubleshooting +--------------- + +If you need help with troubleshooting your system, please first check `ROS Answers `__ to see if others have come across similar issues, otherwise ask a new questions on ROS Answers making sure to include at least the ``ros2`` tag and the rosdistro version you are running, e.g. ``ardent``. + +Opening issues +-------------- + +If you identify bugs, you can open an issue to notify the ROS team. +Before opening an issue, check if other users have reported similar issues by searching across the ros2 and ament Github organizations: `example search query `__. + +If it has not been reported, feel free to open an issue in the appropriate repository tracker. +If it's not clear which tracker to use for a particular issue, file it in the `ros2/ros2 repository `__ and we'll have a look at it. +When filing an issue, please make sure to: + + +* Include enough information for another person to understand the issue. +* Include information about the exact platform, software, versions, and environment relevant to the problem. This includes how you installed the software (from binaries or from source) and which ROS middleware/DDS vendor you are using (if you know it). +* In case of a bug consider providing a `short, self contained, correct (compilable), example `__. + +Pull requests are welcome for any of `the ros2 repositories `__ to suggest specific code changes! +See `Contributing ` for more details on how to contribute. diff --git a/Contributing.md b/Contributing.md deleted file mode 100644 index d8c81bc2eda..00000000000 --- a/Contributing.md +++ /dev/null @@ -1,42 +0,0 @@ -# Contributing to ROS 2 - -There are a number of ways you can contribute to the ROS 2 project. - -## Design discussions - -Discussions about the design of ROS 2 are ongoing on the [ROS 2 forum](http://discourse.ros.org/c/ng-ros). -Participating in these discussions is an important way to have a say on the how different features of ROS 2 will work and will be implemented. - -The diverse community behind the ROS ecosystem is one of its greatest assets. -We encourage all members of the ROS community to participate in these design discussions so that we can 1) leverage the experience of community members and 2) keep the varied use cases of ROS in mind. - -## Support - -One of the easiest ways that you can contribute to ROS 2 is by helping other community members troubleshoot their system. -ROS 2 users come from a range of technical backgrounds, use a variety of different operating systems/platforms, and don’t necessarily have any prior experience with ROS (1 or 2). - -If you see an issue on the [ROS Answers](https://answers.ros.org) that is similar to something you’ve run into yourself, please consider providing some pointers to what helped in your situation. -Don’t worry if you are not sure if your response is correct - simply say so and other community members will jump in if necessary. - -## Contributing code - -### Setting up your development environment - -To get started, you'll want to install from source; follow [the source installation instructions](Installation.md#building-from-source) for your platform. - -### What to work on - -We have identified a number of tasks that could be worked on by community members: they can be listed by [searching across the ROS 2 repositories for issues labeled as "help wanted"](https://github.com/search?q=user%3Aament+user%3Aros2+is%3Aopen+label%3A"help+wanted"&type=Issues) or filtering the items on [the ROS 2 waffle.io board](https://waffle.io/ros2/ros2?search=help%20wanted). -If you see something on that list that you would like to work on, please comment on the item to let others know that you are looking into it. - -If you have some code to contribute that fixes a bug or improves documentation, please submit it as a pull request to the relevant repository. -For larger changes, it is a good idea to discuss the proposal [on the ROS 2 forum](http://discourse.ros.org/c/ng-ros) before you start to work on it so that you can identify if someone else is already working on something similar. -If your proposal involves changes to the APIs, it is especially recommended that you discuss the approach before starting work. - -### Submitting your code changes - -Code contributions should be made via pull requests to [the appropriate ros2 repositories](https://github.com/ros2). - -We ask all contributors to follow the practices explained in [the developer guide](Developer-Guide.md). - -Please be sure to [run tests](Colcon-Tutorial.md#run-the-tests) for your code changes because most packages have tests that check that the code complies with our style guidelines. diff --git a/Contributing.rst b/Contributing.rst new file mode 100644 index 00000000000..1a156492cb3 --- /dev/null +++ b/Contributing.rst @@ -0,0 +1,50 @@ + +Contributing to ROS 2 +===================== + +There are a number of ways you can contribute to the ROS 2 project. + +Design discussions +------------------ + +Discussions about the design of ROS 2 are ongoing on the `ROS 2 forum `__. +Participating in these discussions is an important way to have a say on the how different features of ROS 2 will work and will be implemented. + +The diverse community behind the ROS ecosystem is one of its greatest assets. +We encourage all members of the ROS community to participate in these design discussions so that we can 1) leverage the experience of community members and 2) keep the varied use cases of ROS in mind. + +Support +------- + +One of the easiest ways that you can contribute to ROS 2 is by helping other community members troubleshoot their system. +ROS 2 users come from a range of technical backgrounds, use a variety of different operating systems/platforms, and don’t necessarily have any prior experience with ROS (1 or 2). + +If you see an issue on the `ROS Answers `__ that is similar to something you’ve run into yourself, please consider providing some pointers to what helped in your situation. +Don’t worry if you are not sure if your response is correct - simply say so and other community members will jump in if necessary. + +Contributing code +----------------- + +Setting up your development environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To get started, you'll want to install from source; follow `the source installation instructions ` for your platform. + +What to work on +^^^^^^^^^^^^^^^ + +We have identified a number of tasks that could be worked on by community members: they can be listed by `searching across the ROS 2 repositories for issues labeled as "help wanted" `__ or filtering the items on `the ROS 2 waffle.io board `__. +If you see something on that list that you would like to work on, please comment on the item to let others know that you are looking into it. + +If you have some code to contribute that fixes a bug or improves documentation, please submit it as a pull request to the relevant repository. +For larger changes, it is a good idea to discuss the proposal `on the ROS 2 forum `__ before you start to work on it so that you can identify if someone else is already working on something similar. +If your proposal involves changes to the APIs, it is especially recommended that you discuss the approach before starting work. + +Submitting your code changes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Code contributions should be made via pull requests to `the appropriate ros2 repositories `__. + +We ask all contributors to follow the practices explained in `the developer guide `. + +Please be sure to `run tests ` for your code changes because most packages have tests that check that the code complies with our style guidelines. diff --git a/DDS-and-ROS-middleware-implementations.md b/DDS-and-ROS-middleware-implementations.md deleted file mode 100644 index c6d8f76969a..00000000000 --- a/DDS-and-ROS-middleware-implementations.md +++ /dev/null @@ -1,30 +0,0 @@ -# ROS 2 and different DDS/RTPS vendors - -ROS 2 is built on top of DDS/RTPS as its middleware, which provides discovery, serialization and transportation. -[This article](http://design.ros2.org/articles/ros_on_dds.html) explains the motivation behind using DDS implementations, and/or the RTPS wire protocol of DDS, in detail, but in summary DDS is an end-to-end middleware that provides features which are relevant to ROS systems, such as distributed discovery (not centralized like in ROS 1) and control over different "Quality of Service" options for the transportation. - -[DDS](http://portals.omg.org/dds/) is an industry standard which is then implemented by a range of vendors, such as RTI's implementation [Connext](https://www.rti.com/products/) or ADLink's implementation [OpenSplice](https://github.com/ADLINK-IST/opensplice) -RTPS (a.k.a. [DDSI-RTPS](https://www.omg.org/spec/DDSI-RTPS/About-DDSI-RTPS/)) is the wire protocol used by DDS to communicate over the network, and there are implementations of that which do not fulfill the full DDS API, but provide sufficient functionality for ROS 2, such as eProsima's implementation [Fast RTPS](http://www.eprosima.com/index.php/products-all/eprosima-fast-rtps). - -ROS 2 supports multiple DDS/RTPS implementations because it is not necessarily "one size fits all" when it comes to choosing a vendor/implementation. -There are many factors you might consider while choosing a middleware implementation: logistical considerations like the license, or technical considerations like platform availability, or computation footprint. -Vendors may provide more than one DDS or RTPS implementation targeted at meeting different needs. -For example, RTI has a few variations of their Connext implementation that vary in purpose, like one that specifically targets microcontrollers and another which targets applications requiring special safety certifications (we only support their standard desktop version at this time). - -In order to use a DDS/RTPS implementation with ROS 2, a "**R**OS **M**iddle**w**are interface" (a.k.a. `rmw` interface or just `rmw`) package needs to be created that implements the abstract ROS middleware interface using the DDS or RTPS implementation's API and tools. -It's a lot of work to implement and maintain RMW packages for supporting DDS implementations, but supporting at least a few implementations is important for ensuring that the ROS 2 codebase is not tied to any one particular implementation, as users may wish to switch out implementations depending on their project's needs. - -### Supported RMW implementations - -| Product name | License | RMW implementation | Status | -| ------------- | ------------- | ----- | ---- | -| eProsima _Fast RTPS_ | Apache 2 | `rmw_fastrtps_cpp` | Full support. Default RMW. Packaged with binary releases. | -| RTI _Connext_ | commercial, research | `rmw_connext_cpp` | Full support. Support included in binaries, but Connext installed separately. | -| RTI _Connext_ (dynamic implementation) | commercial, research | `rmw_connext_dynamic_cpp` | Support paused. Full support until alpha 8.* | -| PrismTech _Opensplice_ | LGPL (only v6.4), commercial | `rmw_opensplice_cpp` | Partial support. Support included in binaries, but OpenSplice installed separately. | -| OSRF _FreeRTPS_ | Apache 2 | -- | Partial support. Development paused. | - - -_"Partial support" means that one or more of the features required by the rmw interface is not implemented._ - -For practical information on working with multiple RMW implementations, see the [Working with multiple RMW implementations](Working-with-multiple-RMW-implementations.md) page. \ No newline at end of file diff --git a/DDS-and-ROS-middleware-implementations.rst b/DDS-and-ROS-middleware-implementations.rst new file mode 100644 index 00000000000..014a5a11141 --- /dev/null +++ b/DDS-and-ROS-middleware-implementations.rst @@ -0,0 +1,53 @@ + +ROS 2 and different DDS/RTPS vendors +==================================== + +ROS 2 is built on top of DDS/RTPS as its middleware, which provides discovery, serialization and transportation. +`This article `__ explains the motivation behind using DDS implementations, and/or the RTPS wire protocol of DDS, in detail, but in summary DDS is an end-to-end middleware that provides features which are relevant to ROS systems, such as distributed discovery (not centralized like in ROS 1) and control over different "Quality of Service" options for the transportation. + +`DDS `__ is an industry standard which is then implemented by a range of vendors, such as RTI's implementation `Connext `__ or ADLink's implementation `OpenSplice `__ +RTPS (a.k.a. `DDSI-RTPS `__\ ) is the wire protocol used by DDS to communicate over the network, and there are implementations of that which do not fulfill the full DDS API, but provide sufficient functionality for ROS 2, such as eProsima's implementation `Fast RTPS `__. + +ROS 2 supports multiple DDS/RTPS implementations because it is not necessarily "one size fits all" when it comes to choosing a vendor/implementation. +There are many factors you might consider while choosing a middleware implementation: logistical considerations like the license, or technical considerations like platform availability, or computation footprint. +Vendors may provide more than one DDS or RTPS implementation targeted at meeting different needs. +For example, RTI has a few variations of their Connext implementation that vary in purpose, like one that specifically targets microcontrollers and another which targets applications requiring special safety certifications (we only support their standard desktop version at this time). + +In order to use a DDS/RTPS implementation with ROS 2, a "\ **R**\ OS **M**\ iddle\ **w**\ are interface" (a.k.a. ``rmw`` interface or just ``rmw``\ ) package needs to be created that implements the abstract ROS middleware interface using the DDS or RTPS implementation's API and tools. +It's a lot of work to implement and maintain RMW packages for supporting DDS implementations, but supporting at least a few implementations is important for ensuring that the ROS 2 codebase is not tied to any one particular implementation, as users may wish to switch out implementations depending on their project's needs. + +Supported RMW implementations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + + * - Product name + - License + - RMW implementation + - Status + * - eProsima *Fast RTPS* + - Apache 2 + - ``rmw_fastrtps_cpp`` + - Full support. Default RMW. Packaged with binary releases. + * - RTI *Connext* + - commercial, research + - ``rmw_connext_cpp`` + - Full support. Support included in binaries, but Connext installed separately. + * - RTI *Connext* (dynamic implementation) + - commercial, research + - ``rmw_connext_dynamic_cpp`` + - Support paused. Full support until alpha 8.* + * - PrismTech *Opensplice* + - LGPL (only v6.4), commercial + - ``rmw_opensplice_cpp`` + - Partial support. Support included in binaries, but OpenSplice installed separately. + * - OSRF *FreeRTPS* + - Apache 2 + - -- + - Partial support. Development paused. + + +*"Partial support" means that one or more of the features required by the rmw interface is not implemented.* + +For practical information on working with multiple RMW implementations, see the `Working with multiple RMW implementations ` page. diff --git a/Defining-custom-interfaces-(msg-srv).md b/Defining-custom-interfaces-(msg-srv).md deleted file mode 100644 index 0cd3c7171ca..00000000000 --- a/Defining-custom-interfaces-(msg-srv).md +++ /dev/null @@ -1,9 +0,0 @@ -# Defining custom interfaces (msg/srv) - -**INCOMPLETE** - -While we encourage reuse of existing "standard" message and service definitions wherever possible, there are plenty of cases in which you'll need to define your own custom messages and/or services for a particular application. -The first step in defining a custom message or service is to write the `.msg` or `.srv` file, which you do using the [ROS interface definition language](About-ROS-Interfaces). -By convention, `.msg` files go into a package subdirectory called `msg` and `.srv` files go into a package subdirectory called `srv` (you can pick different locations, but we recommend following the convention). - -Having written your `.msg` and/or `.srv` files, you need to add some code to your package's `CMakelists.txt` file to make the code generators run over your definitions. In lieu of a more complete tutorial on this topic, consult the [pendulum_msgs package](https://github.com/ros2/demos/tree/master/pendulum_msgs) as an example. You can see the relevant CMake calls in that packages's [CMakeLists.txt file](https://github.com/ros2/demos/blob/master/pendulum_msgs/CMakeLists.txt). \ No newline at end of file diff --git a/Defining-custom-interfaces-(msg-srv).rst b/Defining-custom-interfaces-(msg-srv).rst new file mode 100644 index 00000000000..8641500e541 --- /dev/null +++ b/Defining-custom-interfaces-(msg-srv).rst @@ -0,0 +1,11 @@ + +Defining custom interfaces (msg/srv) +==================================== + +**INCOMPLETE** + +While we encourage reuse of existing "standard" message and service definitions wherever possible, there are plenty of cases in which you'll need to define your own custom messages and/or services for a particular application. +The first step in defining a custom message or service is to write the ``.msg`` or ``.srv`` file, which you do using the `ROS interface definition language `. +By convention, ``.msg`` files go into a package subdirectory called ``msg`` and ``.srv`` files go into a package subdirectory called ``srv`` (you can pick different locations, but we recommend following the convention). + +Having written your ``.msg`` and/or ``.srv`` files, you need to add some code to your package's ``CMakelists.txt`` file to make the code generators run over your definitions. In lieu of a more complete tutorial on this topic, consult the `pendulum_msgs package `__ as an example. You can see the relevant CMake calls in that packages's `CMakeLists.txt file `__. diff --git a/Design-Guide.md b/Design-Guide.rst similarity index 52% rename from Design-Guide.md rename to Design-Guide.rst index ae14a8e52df..6cf0701945b 100644 --- a/Design-Guide.md +++ b/Design-Guide.rst @@ -1,4 +1,6 @@ -# Composable nodes as shared libraries + +Composable nodes as shared libraries +==================================== **Context** @@ -6,15 +8,18 @@ You want to export composable nodes as a shared libraries from some packages and **Solution** + * add code to the CMake file which imports the actual targets in downstream packages + * install the generated file * export the generated file **Example** -[ROS Discourse - Ament best practice for sharing libraries](https://discourse.ros.org/t/ament-best-practice-for-sharing-libraries/3602) +`ROS Discourse - Ament best practice for sharing libraries `__ -# FastRTPS large data transfer +FastRTPS large data transfer +============================ **Context** @@ -32,15 +37,16 @@ configure the middleware that it fragements large data into messages use Asynchronous publication mode: -``` - - ASYNCHRONOUS - -``` +.. code-block:: + + + ASYNCHRONOUS + -[ROS2 Fine Tuning](https://roscon.ros.org/2017/presentations/ROSCon%202017%20ROS2%20Fine%20Tuning.pdf) +`ROS2 Fine Tuning `__ -# FastRTPS Best Effort Video Streaming +FastRTPS Best Effort Video Streaming +==================================== **Context** @@ -59,23 +65,25 @@ mechanism) and prioritize the last frame. **Implementation** + * configure "best effort" reliability mechanism * configure Quality of service history to keep last frame -``` - - BEST_EFFORT - +.. code-block:: + + + BEST_EFFORT + - - KEEP_LAST - 1 - -``` + + KEEP_LAST + 1 + -[ROS2 Fine Tuning](https://roscon.ros.org/2017/presentations/ROSCon%202017%20ROS2%20Fine%20Tuning.pdf) +`ROS2 Fine Tuning `__ -# FastRTPS Reliable Video Streaming +FastRTPS Reliable Video Streaming +================================= **Context** @@ -87,31 +95,32 @@ Use a reliable communication mechanism. Use fast response by writer and reader. **Implementation** + * configure "reliable" reliability mechanism * configure NACK reponse delay and suppression duration of writer to 0 * configure heartbeat response delay of reader to 0 -``` - - RELIABLE - - -# writer - - - ZERO - - - ZERO - - - -# reader - - - ZERO - - -``` - -[ROS2 Fine Tuning](https://roscon.ros.org/2017/presentations/ROSCon%202017%20ROS2%20Fine%20Tuning.pdf) \ No newline at end of file +.. code-block:: + + + RELIABLE + + + # writer + + + ZERO + + + ZERO + + + + # reader + + + ZERO + + + +`ROS2 Fine Tuning `__ diff --git a/Developer-Guide.md b/Developer-Guide.md deleted file mode 100644 index b3f4b3f88fb..00000000000 --- a/Developer-Guide.md +++ /dev/null @@ -1,591 +0,0 @@ -# ROS 2 Developer Guide - -This page defines the practices and policies we employ when developing ROS 2. - -## Table of Contents - -- [General Principles](#general-principles) -- [General Practices](#general-practices) -- [Language Versions and Code Format](#language-versions-and-code-format) - - [C](#c) - - [C++](#c-1) - - [Python](#python) - - [CMake](#cmake) - - [Markdown](#markdown) -- [Testing](#testing) -- [Versioning](#versioning) -- [Filesystem layout](#filesystem-layout) -- [Documentation](#documentation) - -## General Principles - -Some principles are common to all ROS 2 development: - -- **Shared ownership**: Everybody working on ROS2 should feel ownership over all parts of the system. - The original author of a chunk of code does not have any special permission or obligation to control or maintain that chunk of code. - Everyone is free to propose changes anywhere, to handle any type of ticket, and to review any pull request. -- **Be willing to work on anything**: As a corollary to shared ownership, everybody should be willing to take on any available task and contribute to any aspect of the system. -- **Ask for help**: If you run into trouble on something, ask your fellow developers for help, via tickets, comments, or email, as appropriate. - -## General Practices - -Some practices are common to all ROS 2 development: - -### Issues - -When filing an issue please make sure to: - -- Include enough information for another person to understand the issue. -- In case of a bug consider to provide a [short, self contained, correct (compilable), example](http://sscce.org/). - -### Pull requests - -- A pull request should only focus on one change. - Separate changes should go into separate pull requests. - See [GitHub's guide to writing the perfect pull request](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) -- A patch should be minimal in size and avoid any kind of unnecessary changes. -- Always run CI jobs for all platforms for every pull request and include links to jobs in the pull request. - (If you don't have access to the Jenkins job someone will trigger the jobs for you.) -- Before merging a pull request all changes should be squashed into a small number of semantic commits to keep the history clear. - - But avoid squashing commits while a pull request is under review. - Your reviewers might not notice that you made the change, thereby introducing potential for confusion. - Plus, you're going to squash before merging anyway; there's no benefit to doing it early. -- A minimum of 1 `+1` from a fellow developer is required to consider a pull request to be approved, which is required before merging. -- Any developer is welcome to review and approve a pull request (see [General Principles](#general-principles)). -- When you start reviewing a pull request, comment on the pull request so that other developers know that you're reviewing it. -- Pull-request review is not read-only, with the reviewer making comments and then waiting for the author to address them. - As a reviewer, feel free to make minor improvements (typos, style issues, etc.) in-place. - As the opener of a pull-request, if you are working in a fork, checking the box to [allow edits from upstream contributors](https://github.com/blog/2247-improving-collaboration-with-forks) will assist with the aforementioned. - As a reviewer, also feel free to make more substantial improvements, but consider putting them in a separate branch (either mention the new branch in a comment, or open another pull request from the new branch to the original branch). -- Any developer (the author, the reviewer, or somebody else) can merge any approved pull request. - -### Development Process - -- The default branch (in most cases the master branch) must always build, pass all tests and compile without warnings. - If at any time there is a regression it is the top priority to restore at least the previous state. -- Always build with tests enabled. -- Always run tests locally after changes and before proposing them in a pull request. - Besides using automated tests, also run the modified code path manually to ensure that the patch works as intended. -- Always run CI jobs for all platforms for every pull request and include links to the jobs in the pull request. - -### kanban board (waffle.io) - -To help organize the work, the core ROS 2 development team is using a kanban system hosted at waffle.io: [ROS 2 kanban](https://waffle.io/ros2/ros2). -This board augments the capabilities of GitHub by using labels to give a custom view into issues and pull requests across multiple repositories. -The data produced and edited via waffle.io are stored in the underlying GitHub objects, so there's no requirement to use waffle.io (or for the core team to be tied to it); it just provides a useful perspective on things. - -Here's how we're using the columns in the board: - -* **Backlog**: cards (issues) that nobody is yet working on. -Their order in the backlog is an approximate indicator of priority, with cards higher in the column having higher priority. -* **Ready**: cards on which work will be started very soon. -Cards in this column should have an owner assigned. -Cards should not sit in this column for more than a few days. -* **In Progress**: cards on which work is currently in progress. -Cards in this column must have an owner assigned. -Cards should not sit in this column for more than a week. -When it is determined that a card will take longer, break it up into multiple cards and put the extras in the backlog. -* **In Review**: cards for which the work is done and the relevant pull request/s is/are ready for review. -Cards remain in this column during review, but if review uncovers significant extra work to be done, move the card into an earlier column as appropriate. -* **Done**: cards for which the work is done, meaning that the relevant pull request/s has/have been merged. -This column shows recently completed cards, for informational purposes only. - -Tips for working with the kanban board: - -* Requesting permission to make changes: Simply comment on specific tickets that you want to work on it. Depending on the complexity it might be useful to describe how you want to address it. We will update the status (if you don't have the permission) and you can start working on a pull request. If you contribute regularly we will likely just grant you permission to manage the labels etc. yourself. -* Using markup to connect issues and pull requests: see the waffle.io FAQ: https://github.com/waffleio/waffle.io/wiki/FAQs#prs-connect-keywords -* Doing equivalent things outside waffle.io, directly via GitHub: The column a card is in is determined by the label. The first and last column do not require a specific label. For the other column a label with the same name can be assigned. - -### Programming conventions - -- Defensive programming: ensure that assumptions are held as early as possible. - E.g. check every return code and make sure to at least throw an exception until the case is handled more gracefully. -- All error messages must be directed to `stderr`. -- Declare variables in the narrowest scope possible. -- Keep group of items (dependencies, imports, includes, etc.) ordered alphabetically. - -#### C++ specific - -- Avoid using direct streaming (`<<`) to `stdout` / `stderr` to prevent interleaving between multiple threads. -- Avoid using references for `std::shared_ptr` since that subverts the reference counting. If the original instance goes out of scope and the reference is being used it accesses freed memory. - -## Language Versions and Code Format - -In order to achieve a consistent looking product we will all follow externally (if possible) defined style guidelines for each language. -For other things like package layout or documentation layout we will need to come up with our own guidelines, drawing on current, popular styles in use now. - -Additionally, where ever possible, developers should use integrated tools to allow them to check that these guidelines are followed in their editors. -For example, everyone should have a PEP8 checker built into their editor to cut down on review iterations related to style. - -Also where possible, packages should check style as part of their unit tests to help with the automated detection of style issues (see [ament_lint_auto](https://github.com/ament/ament_lint/blob/master/ament_lint_auto/doc/index.rst)). - -### C - -We will target C99. - -We will use Python's PEP7 for our C style guide, with some modifications and additions: - -http://legacy.python.org/dev/peps/pep-0007/ - -Some modifications and additions: - -- We will target C99, as we do not need to support C89 (as PEP7 recommends) - - rationale: among other things it allows us to use both `//` and `/* */` style comments - - rationale: C99 is pretty much ubiquitous now -- C++ style `//` comments are allowed -- Always place literals on the left hand side of comparison operators, e.g. `0 == ret` instead of `ret == 0` - - rationale: `ret == 0` too easily turns into `ret = 0` by accident - -All of the following modifications only apply if we are not writing Python modules: - -- Do not use `Py_` as a prefix for everything - - Instead use a CamelCase version of the package name or other appropriate prefix -- The stuff about documentation strings doesn't apply - -We can use the `pep7` python module for style checking: - -https://github.com/mike-perdide/pep7 - -The editor integration seems slim, we may need to looking to automated checking for C in more detail. - -### C++ - -We will target C++14, using new built-in C++14 features over Boost equivalents where ever possible. - -We will use the Google C++ Style Guide, with some modifications: - -https://google.github.io/styleguide/cppguide.html - -#### Line Length - -- Line Length: our maximum line length is 100 characters. - -#### Variable Naming - -- Global variables: use lowercase with underscores prefixed with `g_` - - rationale: keep variable naming case consistent across the project - - rationale: easy to tell the scope of a variable at a glance - - consistency across languages - -#### Access Control - -- Access Control: drop requirement for all class members to be private and therefore require accessors - - rationale: this is overly constraining for user API design - - we should prefer private members, only making them public when they are needed - - we should consider using accessors before choosing to allow direct member access - - we should have a good reason for allowing direct member access, other than because it is convenient for us - -#### Exceptions - -- Exceptions are allowed - - rationale: this is a new code base, so the legacy argument doesn't apply to us - - rationale: for user facing API's it is more idiomatic C++ to have exceptions - - Exceptions in destructors should be explicitly avoided -- We should consider avoiding Exceptions if we intend to wrap the resulting API in C - - rationale: it will make it easier to wrap in C - - rationale: most of our dependencies in code we intend to wrap in C do not use exceptions anyways - -#### Function-like Objects - -- No restrictions on Lambda's or `std::function` or `std::bind` - -#### Boost - -- Boost should be avoided until absolutely required - -#### Comments and Doc Comments - -- Use `///` and `/** */` comments for _documentation_ purposes and `//` style comments for notes and general comments - - Class and Function comments should use `///` and `/** */` style comments - - rationale: these are recommended for Doxygen and Sphinx in C/C++ - - rationale: mixing `/* */` and `//` is convenient for block commenting out code which contains comments - - Descriptions of how the code works or notes within classes and functions should use `//` style comments - -#### Pointer Syntax Alignment - -- Use `char * c;` instead of `char* c;` or `char *c;` because of this scenario `char* c, *d, *e;` - -#### Class Privacy Keywords - -- Do not put 1 space before `public:`, `private:`, or `protected:`, it is more consistent for all indentions to be a multiple of 2 - - rationale: most editors don't like indentions which are not a multiple of the (soft) tab size - - Use zero spaces before `public:`, `private:`, or `protected:`, or 2 spaces - - If you use 2 spaces before, indent other class statements by 2 additional spaces - - Prefer zero spaces, i.e. `public:`, `private:`, or `protected:` in the same column as the class - -#### Nested Templates - -- Never add whitespace to nested templates - - Prefer `set>` (C++11 feature) to `set >` or `set< list >` - -#### Always Use Braces - -- Always use braces following `if`, `else`, `do`, `while`, and `for`, even when the body is a single line. - - rationale: less opportunity for visual ambiguity and for complications due to use of macros in the body - -#### Open Versus Cuddled Braces - -- Use open braces for `function`, `class`, and `struct` definitions, but cuddle braces on `if`, `else`, `while`, `for`, etc... - - Exception: when an `if` (or `while`, etc.) condition is long enough to require line-wrapping, then use an open brace (i.e., don't cuddle). -- When a function call cannot fit on one line, wrap at the open parenthesis (not in between arguments) and start them on the next line with a 2-space indent. Continue with the 2-space indent on subsequent lines for more arguments. (Note that the [Google guide](https://google.github.io/styleguide/cppguide.html#Function_Calls) is internally contradictory on this point.) - - Same goes for `if` (and `while`, etc.) conditions that are too long to fit on one line. - -##### Examples - -This is OK: - -```c++ -int main(int argc, char **argv) -{ - if (condition) { - return 0; - } else { - return 1; - } -} - -if (this && that || both) { - ... -} - -// Long condition; open brace -if ( - this && that || both && this && that || both && this && that || both && this && that) -{ - ... -} - -// Short function call -call_func(foo, bar); - -// Long function call; wrap at the open parenthesis -call_func( - foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, - foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar); - -// Very long function argument; separate it for readability -call_func( - bang, - fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, - bar, bat); -``` - -Bad: - -```c++ -int main(int argc, char **argv) { - return 0; -} - -if (this && - that || - both) { - ... -} -``` - -- Use open braces rather than excessive indention, e.g. for distinguishing constructor code from constructor initializer lists - -OK: - -```c++ -ReturnType LongClassName::ReallyReallyReallyLongFunctionName( - Type par_name1, // 2 space indent - Type par_name2, - Type par_name3) -{ - DoSomething(); // 2 space indent - ... -} - -MyClass::MyClass(int var) -: some_var_(var), - some_other_var_(var + 1) -{ - ... - DoSomething(); - ... -} -``` - -Bad, weird (the google way?): - -```c++ -ReturnType LongClassName::ReallyReallyReallyLongFunctionName( - Type par_name1, // 4 space indent - Type par_name2, - Type par_name3) { - DoSomething(); // 2 space indent - ... -} - -MyClass::MyClass(int var) - : some_var_(var), // 4 space indent - some_other_var_(var + 1) { // lined up - ... - DoSomething(); - ... -} -``` - -#### Linters - -Most of these styles and restrictions can be checked with a combination of Google's [cpplint.py](http://google-styleguide.googlecode.com/svn/trunk/cpplint/) and [uncrustify](https://github.com/uncrustify/uncrustify), though we may need to modify them slightly for our above changes. - -We provide command line tools with custom configurations: -- [`ament_cpplint`](https://github.com/ament/ament_lint/blob/master/ament_cpplint/doc/index.rst) -- [`ament_uncrustify`](https://github.com/ament/ament_lint/blob/master/ament_uncrustify/doc/index.rst): [configuration](https://github.com/ament/ament_lint/blob/master/ament_uncrustify/ament_uncrustify/configuration/ament_code_style.cfg) - -We also run other tools to detect and eliminate as many warnings as possible. -Here's a non-exhaustive list of additional things we try to do on all of our packages: - -- use compiler flags like `-Wall -Wextra -Wpedantic` -- run static code analysis like `cppcheck`, which we have integrated in [`ament_cppcheck`](https://github.com/ament/ament_lint/blob/master/ament_cppcheck/doc/index.rst) - - -### Python - -We will target Python 3 for our development. - -We will use the PEP8 guidelines for code format: - -http://legacy.python.org/dev/peps/pep-0008/ - -We chose the following more precise rule where PEP 8 leaves some freedom: - -- We allow up to 100 character per line (fifth paragraph http://legacy.python.org/dev/peps/pep-0008/#maximum-line-length) -- We pick single quotes over double quotes as long as no escaping is necessary (http://legacy.python.org/dev/peps/pep-0008/#string-quotes) - -Tools like the `(ament_)pep8` Python package should be used in unit-test and/or editor integration for checking Python code style. - -The pep8 configuration used in the linter is [here](https://github.com/ament/ament_lint/blob/master/ament_pep8/ament_pep8/configuration/ament_pep8.ini) - -Integration with editors: - -- atom: https://atom.io/packages/linter-pep8 -- emacs: http://kwbeam.com/emacs-for-python-i.html -- Sublime Text: https://sublime.wbond.net/packages/SublimeLinter-flake8 -- vim: https://github.com/nvie/vim-flake8 - -### CMake - -We will target CMake 3.5. - -Since there is not an existing CMake style guide we will define our own: - -- Use lowercase keywords (functions and macros) -- Use empty `else()` and `end...()` commands -- No whitespace before `(`'s -- Use two spaces of indention, do not use tabs -- Do not use aligned indentation for parameters of multi-line macro invocations. Use two spaces only. -- Prefer functions with `set(PARENT_SCOPE)` to macros -- When using macros prefix local variables with `_` or a reasonable prefix - -### Markdown - -The following rules to format the markdown syntax is intended to increase readability as well as versioning. - -- Each section title should be preceded by one empty line and succeeded by one empty line. - - Rationale: It expedites to get an overview about the structure when screening the document. -- Each sentence must start on a new line. - - Rationale: For longer paragraphs a single change in the beginning makes the diff unreadable since it carries forward through the whole paragraph. -- Each sentence can optionally be wrapped to keep each line short. -- The lines should not have any trailing white spaces. -- A code block must be preceded and succeeded by an empty line. - - Rationale: Whitespace is significant only directly before and directly after fenced code blocks. - Following these instructions will ensure that highlighting works properly and consistently. -- A code block should specify a syntax after the opening triple backticks. - -### Javascript - -*(Speculative, not yet used)* - -We will target Javascript 1.5, which seems to provide the best balance of support in browsers and languages (node.js) and new features. - -We will use the airbnb Javascript Style guide: - -https://github.com/airbnb/javascript - -The above repository comes with a `jshintrc` file which allows the style to be enforced using `jshint`. -Editor integration for `jshint` include `vim`, `emacs`, `Sublime Text`, and others: - -http://www.jshint.com/install/ - -## Testing - -All packages should have some level of tests. -Tests can be broken down into three main categories, System tests, Integration tests, and Unit tests. - -Unit tests should always be in the package which is being tested and should make use of tools like `Mock` to try and test narrow parts of the code base in constructed scenarios. -Unit tests should not bring in test dependencies that are not testing tools, e.g. gtest, nosetest, pytest, mock, etc... - -Integration tests can test interactions between parts of the code or between parts of the code and the system. -They often test software interfaces in ways that we expect the user to use them. -Like Unit tests, Integration tests should be in the package which is being tested and should not bring in non-tool test dependencies unless absolutely necessary, i.e. all non-tool dependencies should only be allowed under extreme scrutiny so they should be avoided if possible. - -System tests are designed to test end-to-end situations between packages and should be in their own packages to avoid bloating or coupling packages and to avoid circular dependencies. - -In general minimizing external or cross package test dependencies should be avoided to prevent circular dependencies and tightly coupled test packages. - -All packages should have some unit tests and possibly integration tests, but the degree to which they should have them is based on the package's category (described later). - -### Test Coverage - -Some packages should have a mechanism setup to capture test coverage information (if applicable to the language). -Coverage tools exist for some of the languages described here including C, C++, and Python, but possibly others. -When possible coverage should be measured in terms of branch coverage, as opposed to statement or function coverage. - -## Versioning - -*(Planned; not yet used)* - -We will use the Semantic Versioning guidelines for versioning: - -http://semver.org/ - -Anything below version `1.0.0` is free to make changes at will and for most of our near-term development this will be the case. -In general though for versions less than `1.0.0` we should increment the `minor` (as `major.minor.patch`) when we break existing API and increment `patch` for anything else. - -Another part of adhering to the Semantic Versioning guidelines is that every package must declare a public API. -The declaration for most C and C++ packages is simple, it is any header that it installs, but it is acceptable to define a set of symbols which are considered private. -When ever possible having private symbols in public headers should be avoided. -For other languages like Python, a public API must be explicitly defined, so that it is clear what symbols can be relied on with respect to the versioning guidelines. -The public API can also be extended to build artifacts like configuration variables, CMake config files, etc. as well as executables and command line options and output. -Any elements of the public API should be clearly stated in the package's documentation. -If something you are using is not explicitly listed as part of the public API in the package's documentation, then you cannot depend on it not changing between minor or patch versions. - -With respect to library versioning, we will version all libraries within a package together. -This means that libraries inherit their version from the package. -This keeps library and package versions from diverging and shares reasoning with the policy of releasing packages which share a repository together. -If you need libraries to have different versions then consider splitting them into different packages. - -### Filesystem Layout - -The filesystem layout of packages and repositories should follow the same conventions in order to provide a consistent experience for users browsing our source code. - -#### Package layout - -- `src`: contains all C and C++ code - - Also contains C/C++ headers which are not installed -- `include`: contains all C and C++ headers which are installed - - ``: for all C and C++ installed headers they should be folder namespaced by the package name -- ``: contains all Python code -- `test`: contains all automated tests and test data -- `doc`: contains all the documentation -- `package.xml`: as defined by [REP-0140](http://www.ros.org/reps/rep-0140.html) (may be updated for prototyping) -- `CMakeLists.txt`: only ROS packages which use CMake -- `setup.py`: only ROS packages which use Python code only -- `README.md`: README which can be rendered on Github as a landing page for the project - - This can be as short or detailed as is convenient, but it should at least link to project documentation - - Consider putting a CI or code coverage tag in this readme - - It can also be `.rst` or anything else that Github supports -- `LICENSE`: A copy of the license or licenses for this package -- `CHANGELOG.rst`: [REP-0132](http://www.ros.org/reps/rep-0132.html) compliant changelog - -#### Repository layout - -Each package should be in a subfolder which has the same name as the package. -If a repository contains only a single package it can optionally be in the root of the repository. - -The root of the repository should have a `CONTRIBUTING.md` file describing the contribution guidelines. -This might include license implication when using e.g. the Apache 2 License. - -## Documentation - -*(API docs are not yet being automatically generated)* - -All packages should have these documentation elements: - -- Description and purpose -- Definition and description of the public API -- Examples -- How to build and install (should reference external tools/workflows) -- How to build and run tests -- How to build documentation -- How to develop (useful for describing things like `python setup.py develop`) - -Each package should describe itself and its purpose or how it is used in the larger scope. -The description should be written, as much as possible, assuming that the reader has stumbled onto it without previous knowledge of ROS or other related projects. - -Each package should define and describe its public API so that there is a reasonable expectation for users what is covered by the semantic versioning policy. -Even in C and C++, where the public API can be enforced by API and ABI checking, it is a good opportunity to describe the layout of the code and the function of each part of the code. - -It should be easy to take any package and from that package's documentation understand how to build, run, build and run tests, and build the documentation. -Obviously we should avoid repeating ourselves for common workflows, like build a package in a workspace, but the basic workflows should be either described or referenced. - -Finally, it should include any documentation for developers. -This might include workflows for testing the code using something like `python setup.py develop`, or it might mean describing how to make use of extension points provided by you package. - -Examples: - -- capabilities: http://docs.ros.org/hydro/api/capabilities/html/ - - This one gives an example of docs which describe the public API -- catkin_tools: https://catkin-tools.readthedocs.org/en/latest/development/extending_the_catkin_command.html - - This is an example of describing an extension point for a package - -### Best Practices - -See [the design guide](Design-Guide.md) - -See [the quality guide](Quality-Guide.md). - -## Package Categories - -*(Planned; not yet used)* - -The policies will apply differently to packages depending on their categorization. -The categories are meant to give some expectation as to the quality of a package and allows us to be more strict or compliant with some packages and less so with others. - -### (Level 1) - -This category should be used for packages which are required for a reasonable ROS system in a production environment. -That is to say that after you remove development tools, build tools, and introspection tools, these packages are still left over as requirements for a basic ROS system to run. -However, just because you can conceive a system which does not need a particular package does not mean that it shouldn't be called 'Level 1', in fact the opposite is true. -If we can imagine that any reasonable production scenario where a package would be used in some essential function, then that package should be considered for this category. -However, packages which we consider essential to getting a robot up and running quickly, but is a generic solution to the problem should probably not start out as 'Level 1'. - -For Example, the packages which provide in-process communication, interprocess communication, generated message runtime code, and component lifecycle should probably all be considered 'Level 1'. -However, a package which provides pose estimation (like `robot_pose_ekf`) is a generic solution something that most people need, but is often replaced with a domain specific solution in production, and therefore it should probably not start out as 'Level 1'. -However, it may upgrade to it at a later date, if it proves to be a solution that people want to use in their products. - -Tools, like `rostopic`, generally do not fall into this category, but are not categorically excluded. -For example, it may be the case the tool which launches and verifies a ROS graph (something like `roslaunch`) may need to be considered 'Level 1' for use in production systems. - -#### Package Requirements - -Requirements to be considered a 'Level 1' package: - -- Have a strictly declared public API -- Have API documentation coverage for public symbols -- Have 100 percent branch code coverage from unit and integration tests -- Have system tests which cover any scenarios covered in documentation -- Have system tests for any corner cases encountered during testing -- Must be >= version 1.0.0 - -#### Change Control Process - -The change control process requires all changes, regardless of trivialness, must go through a pull request. -This is to ensure a complete memoranda of changes to the code base. -In order for a pull request to get merged: - -- Changes must be reviewed by two reviewers -- Commits must be concise and descriptive -- All automated tests must be run in CI on all applicable platforms (Windows, versions of Linux, OS X, ARM) -- Code coverage must stay at 100 percent -- Any changes which require updates to documentation must be made before merging - -### (Level 2) - -These are packages which need to be solidly developed and might be used in production environments, but are not strictly required, or are commonly replaced by custom solutions. -This can also include packages which are not yet up to 'Level 1' but intend to be in the future. - -### (Level 3) - -These are packages which are useful for development purposes or introspection, but are not recommended for use in embedded products or mission critical scenarios. -These packages are more lax on documentation, testing, and scope of public API's in order to make development time lower or foster addition of new features. - -### (Level 4) - -These are demos, tutorials, or experiments. -They don't have strict requirements, but are not excluded from having good documentation or tests. -For example, this might be a tutorial package which is not intended for reuse but has excellent documentation because it serves primarily as an example to others. \ No newline at end of file diff --git a/Developer-Guide.rst b/Developer-Guide.rst new file mode 100644 index 00000000000..55e64b2f673 --- /dev/null +++ b/Developer-Guide.rst @@ -0,0 +1,709 @@ + +ROS 2 Developer Guide +===================== + +This page defines the practices and policies we employ when developing ROS 2. + +Table of Contents +----------------- + + +* `General Principles <#general-principles>` +* `General Practices <#general-practices>` +* `Language Versions and Code Format <#language-versions-and-code-format>` + + * `C <#c>` + * `C++ <#c-1>` + * `Python <#python>` + * `CMake <#cmake>` + * `Markdown <#markdown>` + +* `Testing <#testing>` +* `Versioning <#versioning>` +* `Filesystem layout <#filesystem-layout>` +* `Documentation <#documentation>` + +General Principles +------------------ + +Some principles are common to all ROS 2 development: + + +* **Shared ownership**\ : Everybody working on ROS2 should feel ownership over all parts of the system. + The original author of a chunk of code does not have any special permission or obligation to control or maintain that chunk of code. + Everyone is free to propose changes anywhere, to handle any type of ticket, and to review any pull request. +* **Be willing to work on anything**\ : As a corollary to shared ownership, everybody should be willing to take on any available task and contribute to any aspect of the system. +* **Ask for help**\ : If you run into trouble on something, ask your fellow developers for help, via tickets, comments, or email, as appropriate. + +General Practices +----------------- + +Some practices are common to all ROS 2 development: + +Issues +^^^^^^ + +When filing an issue please make sure to: + + +* Include enough information for another person to understand the issue. +* In case of a bug consider to provide a `short, self contained, correct (compilable), example `__. + +Pull requests +^^^^^^^^^^^^^ + + +* A pull request should only focus on one change. + Separate changes should go into separate pull requests. + See `GitHub's guide to writing the perfect pull request `__ +* A patch should be minimal in size and avoid any kind of unnecessary changes. +* Always run CI jobs for all platforms for every pull request and include links to jobs in the pull request. + (If you don't have access to the Jenkins job someone will trigger the jobs for you.) +* Before merging a pull request all changes should be squashed into a small number of semantic commits to keep the history clear. + + * But avoid squashing commits while a pull request is under review. + Your reviewers might not notice that you made the change, thereby introducing potential for confusion. + Plus, you're going to squash before merging anyway; there's no benefit to doing it early. + +* A minimum of 1 ``+1`` from a fellow developer is required to consider a pull request to be approved, which is required before merging. +* Any developer is welcome to review and approve a pull request (see `General Principles <#general-principles>`\ ). +* When you start reviewing a pull request, comment on the pull request so that other developers know that you're reviewing it. +* Pull-request review is not read-only, with the reviewer making comments and then waiting for the author to address them. + As a reviewer, feel free to make minor improvements (typos, style issues, etc.) in-place. + As the opener of a pull-request, if you are working in a fork, checking the box to `allow edits from upstream contributors `__ will assist with the aforementioned. + As a reviewer, also feel free to make more substantial improvements, but consider putting them in a separate branch (either mention the new branch in a comment, or open another pull request from the new branch to the original branch). +* Any developer (the author, the reviewer, or somebody else) can merge any approved pull request. + +Development Process +^^^^^^^^^^^^^^^^^^^ + + +* The default branch (in most cases the master branch) must always build, pass all tests and compile without warnings. + If at any time there is a regression it is the top priority to restore at least the previous state. +* Always build with tests enabled. +* Always run tests locally after changes and before proposing them in a pull request. + Besides using automated tests, also run the modified code path manually to ensure that the patch works as intended. +* Always run CI jobs for all platforms for every pull request and include links to the jobs in the pull request. + +kanban board (waffle.io) +^^^^^^^^^^^^^^^^^^^^^^^^ + +To help organize the work, the core ROS 2 development team is using a kanban system hosted at waffle.io: `ROS 2 kanban `__. +This board augments the capabilities of GitHub by using labels to give a custom view into issues and pull requests across multiple repositories. +The data produced and edited via waffle.io are stored in the underlying GitHub objects, so there's no requirement to use waffle.io (or for the core team to be tied to it); it just provides a useful perspective on things. + +Here's how we're using the columns in the board: + + +* **Backlog**\ : cards (issues) that nobody is yet working on. + Their order in the backlog is an approximate indicator of priority, with cards higher in the column having higher priority. +* **Ready**\ : cards on which work will be started very soon. + Cards in this column should have an owner assigned. + Cards should not sit in this column for more than a few days. +* **In Progress**\ : cards on which work is currently in progress. + Cards in this column must have an owner assigned. + Cards should not sit in this column for more than a week. + When it is determined that a card will take longer, break it up into multiple cards and put the extras in the backlog. +* **In Review**\ : cards for which the work is done and the relevant pull request/s is/are ready for review. + Cards remain in this column during review, but if review uncovers significant extra work to be done, move the card into an earlier column as appropriate. +* **Done**\ : cards for which the work is done, meaning that the relevant pull request/s has/have been merged. + This column shows recently completed cards, for informational purposes only. + +Tips for working with the kanban board: + + +* Requesting permission to make changes: Simply comment on specific tickets that you want to work on it. Depending on the complexity it might be useful to describe how you want to address it. We will update the status (if you don't have the permission) and you can start working on a pull request. If you contribute regularly we will likely just grant you permission to manage the labels etc. yourself. +* Using markup to connect issues and pull requests: see the waffle.io FAQ: https://github.com/waffleio/waffle.io/wiki/FAQs#prs-connect-keywords +* Doing equivalent things outside waffle.io, directly via GitHub: The column a card is in is determined by the label. The first and last column do not require a specific label. For the other column a label with the same name can be assigned. + +Programming conventions +^^^^^^^^^^^^^^^^^^^^^^^ + + +* Defensive programming: ensure that assumptions are held as early as possible. + E.g. check every return code and make sure to at least throw an exception until the case is handled more gracefully. +* All error messages must be directed to ``stderr``. +* Declare variables in the narrowest scope possible. +* Keep group of items (dependencies, imports, includes, etc.) ordered alphabetically. + +C++ specific +~~~~~~~~~~~~ + + +* Avoid using direct streaming (\ ``<<``\ ) to ``stdout`` / ``stderr`` to prevent interleaving between multiple threads. +* Avoid using references for ``std::shared_ptr`` since that subverts the reference counting. If the original instance goes out of scope and the reference is being used it accesses freed memory. + +Language Versions and Code Format +--------------------------------- + +In order to achieve a consistent looking product we will all follow externally (if possible) defined style guidelines for each language. +For other things like package layout or documentation layout we will need to come up with our own guidelines, drawing on current, popular styles in use now. + +Additionally, where ever possible, developers should use integrated tools to allow them to check that these guidelines are followed in their editors. +For example, everyone should have a PEP8 checker built into their editor to cut down on review iterations related to style. + +Also where possible, packages should check style as part of their unit tests to help with the automated detection of style issues (see `ament_lint_auto `__\ ). + +C +^ + +We will target C99. + +We will use Python's PEP7 for our C style guide, with some modifications and additions: + +http://legacy.python.org/dev/peps/pep-0007/ + +Some modifications and additions: + + +* We will target C99, as we do not need to support C89 (as PEP7 recommends) + + * rationale: among other things it allows us to use both ``//`` and ``/* */`` style comments + * rationale: C99 is pretty much ubiquitous now + +* C++ style ``//`` comments are allowed +* Always place literals on the left hand side of comparison operators, e.g. ``0 == ret`` instead of ``ret == 0`` + + * rationale: ``ret == 0`` too easily turns into ``ret = 0`` by accident + +All of the following modifications only apply if we are not writing Python modules: + + +* Do not use ``Py_`` as a prefix for everything + + * Instead use a CamelCase version of the package name or other appropriate prefix + +* The stuff about documentation strings doesn't apply + +We can use the ``pep7`` python module for style checking: + +https://github.com/mike-perdide/pep7 + +The editor integration seems slim, we may need to looking to automated checking for C in more detail. + +C++ +^^^ + +We will target C++14, using new built-in C++14 features over Boost equivalents where ever possible. + +We will use the Google C++ Style Guide, with some modifications: + +https://google.github.io/styleguide/cppguide.html + +Line Length +~~~~~~~~~~~ + + +* Line Length: our maximum line length is 100 characters. + +Variable Naming +~~~~~~~~~~~~~~~ + + +* Global variables: use lowercase with underscores prefixed with ``g_`` + + * rationale: keep variable naming case consistent across the project + * rationale: easy to tell the scope of a variable at a glance + * consistency across languages + +Access Control +~~~~~~~~~~~~~~ + + +* Access Control: drop requirement for all class members to be private and therefore require accessors + + * rationale: this is overly constraining for user API design + * we should prefer private members, only making them public when they are needed + * we should consider using accessors before choosing to allow direct member access + * we should have a good reason for allowing direct member access, other than because it is convenient for us + +Exceptions +~~~~~~~~~~ + + +* Exceptions are allowed + + * rationale: this is a new code base, so the legacy argument doesn't apply to us + * rationale: for user facing API's it is more idiomatic C++ to have exceptions + * Exceptions in destructors should be explicitly avoided + +* We should consider avoiding Exceptions if we intend to wrap the resulting API in C + + * rationale: it will make it easier to wrap in C + * rationale: most of our dependencies in code we intend to wrap in C do not use exceptions anyways + +Function-like Objects +~~~~~~~~~~~~~~~~~~~~~ + + +* No restrictions on Lambda's or ``std::function`` or ``std::bind`` + +Boost +~~~~~ + + +* Boost should be avoided until absolutely required + +Comments and Doc Comments +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Use ``///`` and ``/** */`` comments for *documentation* purposes and ``//`` style comments for notes and general comments + + * Class and Function comments should use ``///`` and ``/** */`` style comments + * rationale: these are recommended for Doxygen and Sphinx in C/C++ + * rationale: mixing ``/* */`` and ``//`` is convenient for block commenting out code which contains comments + * Descriptions of how the code works or notes within classes and functions should use ``//`` style comments + +Pointer Syntax Alignment +~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Use ``char * c;`` instead of ``char* c;`` or ``char *c;`` because of this scenario ``char* c, *d, *e;`` + +Class Privacy Keywords +~~~~~~~~~~~~~~~~~~~~~~ + + +* Do not put 1 space before ``public:``\ , ``private:``\ , or ``protected:``\ , it is more consistent for all indentions to be a multiple of 2 + + * rationale: most editors don't like indentions which are not a multiple of the (soft) tab size + * Use zero spaces before ``public:``\ , ``private:``\ , or ``protected:``\ , or 2 spaces + * If you use 2 spaces before, indent other class statements by 2 additional spaces + * Prefer zero spaces, i.e. ``public:``\ , ``private:``\ , or ``protected:`` in the same column as the class + +Nested Templates +~~~~~~~~~~~~~~~~ + + +* Never add whitespace to nested templates + + * Prefer ``set>`` (C++11 feature) to ``set >`` or ``set< list >`` + +Always Use Braces +~~~~~~~~~~~~~~~~~ + + +* Always use braces following ``if``\ , ``else``\ , ``do``\ , ``while``\ , and ``for``\ , even when the body is a single line. + + * rationale: less opportunity for visual ambiguity and for complications due to use of macros in the body + +Open Versus Cuddled Braces +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Use open braces for ``function``\ , ``class``\ , and ``struct`` definitions, but cuddle braces on ``if``\ , ``else``\ , ``while``\ , ``for``\ , etc... + + * Exception: when an ``if`` (or ``while``\ , etc.) condition is long enough to require line-wrapping, then use an open brace (i.e., don't cuddle). + +* When a function call cannot fit on one line, wrap at the open parenthesis (not in between arguments) and start them on the next line with a 2-space indent. Continue with the 2-space indent on subsequent lines for more arguments. (Note that the `Google guide `__ is internally contradictory on this point.) + + * Same goes for ``if`` (and ``while``\ , etc.) conditions that are too long to fit on one line. + +Examples +"""""""" + +This is OK: + +.. code-block:: c++ + + int main(int argc, char **argv) + { + if (condition) { + return 0; + } else { + return 1; + } + } + + if (this && that || both) { + ... + } + + // Long condition; open brace + if ( + this && that || both && this && that || both && this && that || both && this && that) + { + ... + } + + // Short function call + call_func(foo, bar); + + // Long function call; wrap at the open parenthesis + call_func( + foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, + foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar); + + // Very long function argument; separate it for readability + call_func( + bang, + fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, + bar, bat); + +Bad: + +.. code-block:: c++ + + int main(int argc, char **argv) { + return 0; + } + + if (this && + that || + both) { + ... + } + + +* Use open braces rather than excessive indention, e.g. for distinguishing constructor code from constructor initializer lists + +OK: + +.. code-block:: c++ + + ReturnType LongClassName::ReallyReallyReallyLongFunctionName( + Type par_name1, // 2 space indent + Type par_name2, + Type par_name3) + { + DoSomething(); // 2 space indent + ... + } + + MyClass::MyClass(int var) + : some_var_(var), + some_other_var_(var + 1) + { + ... + DoSomething(); + ... + } + +Bad, weird (the google way?): + +.. code-block:: c++ + + ReturnType LongClassName::ReallyReallyReallyLongFunctionName( + Type par_name1, // 4 space indent + Type par_name2, + Type par_name3) { + DoSomething(); // 2 space indent + ... + } + + MyClass::MyClass(int var) + : some_var_(var), // 4 space indent + some_other_var_(var + 1) { // lined up + ... + DoSomething(); + ... + } + +Linters +~~~~~~~ + +Most of these styles and restrictions can be checked with a combination of Google's `cpplint.py `__ and `uncrustify `__\ , though we may need to modify them slightly for our above changes. + +We provide command line tools with custom configurations: + + +* `\ ``ament_cpplint`` `__ +* `\ ``ament_uncrustify`` `__\ : `configuration `__ + +We also run other tools to detect and eliminate as many warnings as possible. +Here's a non-exhaustive list of additional things we try to do on all of our packages: + + +* use compiler flags like ``-Wall -Wextra -Wpedantic`` +* run static code analysis like ``cppcheck``\ , which we have integrated in `\ ``ament_cppcheck`` `__ + +Python +^^^^^^ + +We will target Python 3 for our development. + +We will use the PEP8 guidelines for code format: + +http://legacy.python.org/dev/peps/pep-0008/ + +We chose the following more precise rule where PEP 8 leaves some freedom: + + +* We allow up to 100 character per line (fifth paragraph http://legacy.python.org/dev/peps/pep-0008/#maximum-line-length) +* We pick single quotes over double quotes as long as no escaping is necessary (http://legacy.python.org/dev/peps/pep-0008/#string-quotes) + +Tools like the ``(ament_)pep8`` Python package should be used in unit-test and/or editor integration for checking Python code style. + +The pep8 configuration used in the linter is `here `__ + +Integration with editors: + + +* atom: https://atom.io/packages/linter-pep8 +* emacs: http://kwbeam.com/emacs-for-python-i.html +* Sublime Text: https://sublime.wbond.net/packages/SublimeLinter-flake8 +* vim: https://github.com/nvie/vim-flake8 + +CMake +^^^^^ + +We will target CMake 3.5. + +Since there is not an existing CMake style guide we will define our own: + + +* Use lowercase keywords (functions and macros) +* Use empty ``else()`` and ``end...()`` commands +* No whitespace before ``(``\ 's +* Use two spaces of indention, do not use tabs +* Do not use aligned indentation for parameters of multi-line macro invocations. Use two spaces only. +* Prefer functions with ``set(PARENT_SCOPE)`` to macros +* When using macros prefix local variables with ``_`` or a reasonable prefix + +Markdown +^^^^^^^^ + +The following rules to format the markdown syntax is intended to increase readability as well as versioning. + + +* Each section title should be preceded by one empty line and succeeded by one empty line. + + * Rationale: It expedites to get an overview about the structure when screening the document. + +* Each sentence must start on a new line. + + * Rationale: For longer paragraphs a single change in the beginning makes the diff unreadable since it carries forward through the whole paragraph. + +* Each sentence can optionally be wrapped to keep each line short. +* The lines should not have any trailing white spaces. +* A code block must be preceded and succeeded by an empty line. + + * Rationale: Whitespace is significant only directly before and directly after fenced code blocks. + Following these instructions will ensure that highlighting works properly and consistently. + +* A code block should specify a syntax after the opening triple backticks. + +Javascript +^^^^^^^^^^ + +*(Speculative, not yet used)* + +We will target Javascript 1.5, which seems to provide the best balance of support in browsers and languages (node.js) and new features. + +We will use the airbnb Javascript Style guide: + +https://github.com/airbnb/javascript + +The above repository comes with a ``jshintrc`` file which allows the style to be enforced using ``jshint``. +Editor integration for ``jshint`` include ``vim``\ , ``emacs``\ , ``Sublime Text``\ , and others: + +http://www.jshint.com/install/ + +Testing +------- + +All packages should have some level of tests. +Tests can be broken down into three main categories, System tests, Integration tests, and Unit tests. + +Unit tests should always be in the package which is being tested and should make use of tools like ``Mock`` to try and test narrow parts of the code base in constructed scenarios. +Unit tests should not bring in test dependencies that are not testing tools, e.g. gtest, nosetest, pytest, mock, etc... + +Integration tests can test interactions between parts of the code or between parts of the code and the system. +They often test software interfaces in ways that we expect the user to use them. +Like Unit tests, Integration tests should be in the package which is being tested and should not bring in non-tool test dependencies unless absolutely necessary, i.e. all non-tool dependencies should only be allowed under extreme scrutiny so they should be avoided if possible. + +System tests are designed to test end-to-end situations between packages and should be in their own packages to avoid bloating or coupling packages and to avoid circular dependencies. + +In general minimizing external or cross package test dependencies should be avoided to prevent circular dependencies and tightly coupled test packages. + +All packages should have some unit tests and possibly integration tests, but the degree to which they should have them is based on the package's category (described later). + +Test Coverage +^^^^^^^^^^^^^ + +Some packages should have a mechanism setup to capture test coverage information (if applicable to the language). +Coverage tools exist for some of the languages described here including C, C++, and Python, but possibly others. +When possible coverage should be measured in terms of branch coverage, as opposed to statement or function coverage. + +Versioning +---------- + +*(Planned; not yet used)* + +We will use the Semantic Versioning guidelines for versioning: + +http://semver.org/ + +Anything below version ``1.0.0`` is free to make changes at will and for most of our near-term development this will be the case. +In general though for versions less than ``1.0.0`` we should increment the ``minor`` (as ``major.minor.patch``\ ) when we break existing API and increment ``patch`` for anything else. + +Another part of adhering to the Semantic Versioning guidelines is that every package must declare a public API. +The declaration for most C and C++ packages is simple, it is any header that it installs, but it is acceptable to define a set of symbols which are considered private. +When ever possible having private symbols in public headers should be avoided. +For other languages like Python, a public API must be explicitly defined, so that it is clear what symbols can be relied on with respect to the versioning guidelines. +The public API can also be extended to build artifacts like configuration variables, CMake config files, etc. as well as executables and command line options and output. +Any elements of the public API should be clearly stated in the package's documentation. +If something you are using is not explicitly listed as part of the public API in the package's documentation, then you cannot depend on it not changing between minor or patch versions. + +With respect to library versioning, we will version all libraries within a package together. +This means that libraries inherit their version from the package. +This keeps library and package versions from diverging and shares reasoning with the policy of releasing packages which share a repository together. +If you need libraries to have different versions then consider splitting them into different packages. + +Filesystem Layout +^^^^^^^^^^^^^^^^^ + +The filesystem layout of packages and repositories should follow the same conventions in order to provide a consistent experience for users browsing our source code. + +Package layout +~~~~~~~~~~~~~~ + + +* ``src``\ : contains all C and C++ code + + * Also contains C/C++ headers which are not installed + +* ``include``\ : contains all C and C++ headers which are installed + + * ````\ : for all C and C++ installed headers they should be folder namespaced by the package name + +* ````\ : contains all Python code +* ``test``\ : contains all automated tests and test data +* ``doc``\ : contains all the documentation +* `package.xml`: as defined by [REP-0140](http://www.ros.org/reps/rep-0140.html) (may be updated for prototyping) +* ``CMakeLists.txt``\ : only ROS packages which use CMake +* ``setup.py``\ : only ROS packages which use Python code only +* ``README``\ : README which can be rendered on Github as a landing page for the project + + * This can be as short or detailed as is convenient, but it should at least link to project documentation + * Consider putting a CI or code coverage tag in this readme + * It can also be ``.rst`` or anything else that Github supports + +* ``LICENSE``\ : A copy of the license or licenses for this package +* `CHANGELOG.rst`: [REP-0132](http://www.ros.org/reps/rep-0132.html) compliant changelog + +Repository layout +~~~~~~~~~~~~~~~~~ + +Each package should be in a subfolder which has the same name as the package. +If a repository contains only a single package it can optionally be in the root of the repository. + +The root of the repository should have a ``CONTRIBUTING`` file describing the contribution guidelines. +This might include license implication when using e.g. the Apache 2 License. + +Documentation +------------- + +*(API docs are not yet being automatically generated)* + +All packages should have these documentation elements: + + +* Description and purpose +* Definition and description of the public API +* Examples +* How to build and install (should reference external tools/workflows) +* How to build and run tests +* How to build documentation +* How to develop (useful for describing things like ``python setup.py develop``\ ) + +Each package should describe itself and its purpose or how it is used in the larger scope. +The description should be written, as much as possible, assuming that the reader has stumbled onto it without previous knowledge of ROS or other related projects. + +Each package should define and describe its public API so that there is a reasonable expectation for users what is covered by the semantic versioning policy. +Even in C and C++, where the public API can be enforced by API and ABI checking, it is a good opportunity to describe the layout of the code and the function of each part of the code. + +It should be easy to take any package and from that package's documentation understand how to build, run, build and run tests, and build the documentation. +Obviously we should avoid repeating ourselves for common workflows, like build a package in a workspace, but the basic workflows should be either described or referenced. + +Finally, it should include any documentation for developers. +This might include workflows for testing the code using something like ``python setup.py develop``\ , or it might mean describing how to make use of extension points provided by you package. + +Examples: + + +* capabilities: http://docs.ros.org/hydro/api/capabilities/html/ + + * This one gives an example of docs which describe the public API + +* catkin_tools: https://catkin-tools.readthedocs.org/en/latest/development/extending_the_catkin_command.html + + * This is an example of describing an extension point for a package + +Best Practices +^^^^^^^^^^^^^^ + +See `the design guide ` + +See `the quality guide `. + +Package Categories +------------------ + +*(Planned; not yet used)* + +The policies will apply differently to packages depending on their categorization. +The categories are meant to give some expectation as to the quality of a package and allows us to be more strict or compliant with some packages and less so with others. + +(Level 1) +^^^^^^^^^ + +This category should be used for packages which are required for a reasonable ROS system in a production environment. +That is to say that after you remove development tools, build tools, and introspection tools, these packages are still left over as requirements for a basic ROS system to run. +However, just because you can conceive a system which does not need a particular package does not mean that it shouldn't be called 'Level 1', in fact the opposite is true. +If we can imagine that any reasonable production scenario where a package would be used in some essential function, then that package should be considered for this category. +However, packages which we consider essential to getting a robot up and running quickly, but is a generic solution to the problem should probably not start out as 'Level 1'. + +For Example, the packages which provide in-process communication, interprocess communication, generated message runtime code, and component lifecycle should probably all be considered 'Level 1'. +However, a package which provides pose estimation (like ``robot_pose_ekf``\ ) is a generic solution something that most people need, but is often replaced with a domain specific solution in production, and therefore it should probably not start out as 'Level 1'. +However, it may upgrade to it at a later date, if it proves to be a solution that people want to use in their products. + +Tools, like ``rostopic``\ , generally do not fall into this category, but are not categorically excluded. +For example, it may be the case the tool which launches and verifies a ROS graph (something like ``roslaunch``\ ) may need to be considered 'Level 1' for use in production systems. + +Package Requirements +~~~~~~~~~~~~~~~~~~~~ + +Requirements to be considered a 'Level 1' package: + + +* Have a strictly declared public API +* Have API documentation coverage for public symbols +* Have 100 percent branch code coverage from unit and integration tests +* Have system tests which cover any scenarios covered in documentation +* Have system tests for any corner cases encountered during testing +* Must be >= version 1.0.0 + +Change Control Process +~~~~~~~~~~~~~~~~~~~~~~ + +The change control process requires all changes, regardless of trivialness, must go through a pull request. +This is to ensure a complete memoranda of changes to the code base. +In order for a pull request to get merged: + + +* Changes must be reviewed by two reviewers +* Commits must be concise and descriptive +* All automated tests must be run in CI on all applicable platforms (Windows, versions of Linux, OS X, ARM) +* Code coverage must stay at 100 percent +* Any changes which require updates to documentation must be made before merging + +(Level 2) +^^^^^^^^^ + +These are packages which need to be solidly developed and might be used in production environments, but are not strictly required, or are commonly replaced by custom solutions. +This can also include packages which are not yet up to 'Level 1' but intend to be in the future. + +(Level 3) +^^^^^^^^^ + +These are packages which are useful for development purposes or introspection, but are not recommended for use in embedded products or mission critical scenarios. +These packages are more lax on documentation, testing, and scope of public API's in order to make development time lower or foster addition of new features. + +(Level 4) +^^^^^^^^^ + +These are demos, tutorials, or experiments. +They don't have strict requirements, but are not excluded from having good documentation or tests. +For example, this might be a tutorial package which is not intended for reuse but has excellent documentation because it serves primarily as an example to others. diff --git a/Eclipse-Oxygen-with-ROS-2-and-rviz2.md b/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst similarity index 50% rename from Eclipse-Oxygen-with-ROS-2-and-rviz2.md rename to Eclipse-Oxygen-with-ROS-2-and-rviz2.rst index 7b486fb5d67..b147b6affc2 100644 --- a/Eclipse-Oxygen-with-ROS-2-and-rviz2.md +++ b/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst @@ -1,147 +1,295 @@ +.. role:: raw-html-m2r(raw) + :format: html + + Eclipse Oxygen with ROS 2 and rviz2 -##### Table of Content -1. [Setup](#Setup) -2. [Eclipse Indexer](#Eclipse_indexer) -3. [Debugging with eclipse](#Debugging_with_eclipse) +Table of Content +"""""""""""""""" + + +#. `Setup <#Setup>` +#. `Eclipse Indexer <#Eclipse_indexer>` +#. `Debugging with eclipse <#Debugging_with_eclipse>` + +Setup +----- -## Setup We have installed eclipse Oxygen and git. eclipse-git (Egit) is already installed (http://www.eclipse.org/egit/download/) We call the eclipse-workspace the same name as the ros2 package. This is not needed. HINT: We use nested projects and so using one eclipse-workspace for one ROS-2 package, because there are many projects inside even if its one ROS-2 project, it seemed more "clean". -![eclipse-launcher](https://i.imgur.com/ePQaXE3.png) + +.. image:: https://i.imgur.com/ePQaXE3.png + :target: https://i.imgur.com/ePQaXE3.png + :alt: eclipse-launcher + We create a C++ Project -![eclipse-1](https://i.imgur.com/XIsATcN.png) -![eclipse-2](https://i.imgur.com/PNVxEJN.png) +.. image:: https://i.imgur.com/XIsATcN.png + :target: https://i.imgur.com/XIsATcN.png + :alt: eclipse-1 + + + +.. image:: https://i.imgur.com/PNVxEJN.png + :target: https://i.imgur.com/PNVxEJN.png + :alt: eclipse-2 + We choose as Project-name the name of the ROS 2 package. Makefile Project and Other Toolchain. -![eclipse-2](https://i.imgur.com/yt5WkkN.png) + +.. image:: https://i.imgur.com/yt5WkkN.png + :target: https://i.imgur.com/yt5WkkN.png + :alt: eclipse-2 + Then we click on Finish -![eclipse-2](https://i.imgur.com/Ef0tLiP.png) + +.. image:: https://i.imgur.com/Ef0tLiP.png + :target: https://i.imgur.com/Ef0tLiP.png + :alt: eclipse-2 In the "Project explorer" we see our Project. -![eclipse-3](https://i.imgur.com/kYutC7W.png) + +.. image:: https://i.imgur.com/kYutC7W.png + :target: https://i.imgur.com/kYutC7W.png + :alt: eclipse-3 + Inside our Project we create a folder called "src" -![eclipse-4](https://i.imgur.com/6uFtcLT.png) + +.. image:: https://i.imgur.com/6uFtcLT.png + :target: https://i.imgur.com/6uFtcLT.png + :alt: eclipse-4 + Now we import a git repository -![eclipse-5](https://i.imgur.com/pae8YOu.png) + +.. image:: https://i.imgur.com/pae8YOu.png + :target: https://i.imgur.com/pae8YOu.png + :alt: eclipse-5 + We put in the repository URL -![eclipse-6](https://i.imgur.com/HuPcPx9.png) + +.. image:: https://i.imgur.com/HuPcPx9.png + :target: https://i.imgur.com/HuPcPx9.png + :alt: eclipse-6 + IMPORTANT: As destination-folder for the git-repository we use the src-folder of our project we created before. HINT: If you got problems choosing the destination folder path, the eclipse-dialog needs a name in the name field. -![eclipse-7](https://i.imgur.com/arFZfa4.png) + +.. image:: https://i.imgur.com/arFZfa4.png + :target: https://i.imgur.com/arFZfa4.png + :alt: eclipse-7 + Import using the new project wizard -![eclipse-8](https://i.imgur.com/ety2Lxf.png) + +.. image:: https://i.imgur.com/ety2Lxf.png + :target: https://i.imgur.com/ety2Lxf.png + :alt: eclipse-8 + We create a General->Project -![eclipse-9](https://i.imgur.com/rpAjqqW.png) + +.. image:: https://i.imgur.com/rpAjqqW.png + :target: https://i.imgur.com/rpAjqqW.png + :alt: eclipse-9 + Use as project name the same name as the git-repository. This is not needed. IMPORTANT: Use as "Location" the folder we cloned the git repository in. -![eclipse-10](https://i.imgur.com/nEoT0RB.png) + +.. image:: https://i.imgur.com/nEoT0RB.png + :target: https://i.imgur.com/nEoT0RB.png + :alt: eclipse-10 + Now we see the git-project and our project in the Project-Explorer view. We see the same files two times, but only one project is linked with Egit. -![eclipse-11](https://i.imgur.com/sSQ8ooN.png) + +.. image:: https://i.imgur.com/sSQ8ooN.png + :target: https://i.imgur.com/sSQ8ooN.png + :alt: eclipse-11 + We repeat this procedure again. Import git repository pluginlib -![eclipse-12](https://i.imgur.com/hnbscVx.png) + +.. image:: https://i.imgur.com/hnbscVx.png + :target: https://i.imgur.com/hnbscVx.png + :alt: eclipse-12 + IMPORTANT: As "Destination->Directory" we use a folder inside the src-folder. -![eclipse-13](https://i.imgur.com/8Z3hlFL.png) + +.. image:: https://i.imgur.com/8Z3hlFL.png + :target: https://i.imgur.com/8Z3hlFL.png + :alt: eclipse-13 + IMPORTANT: As location for our new project we use the folder we cloned the git repository in -![eclipse-14](https://i.imgur.com/xySYIQi.png) + +.. image:: https://i.imgur.com/xySYIQi.png + :target: https://i.imgur.com/xySYIQi.png + :alt: eclipse-14 + The same procedure again. Now with tinyxml2_vendor git repository. -![eclipse-15](https://i.imgur.com/izC5Hke.png) + +.. image:: https://i.imgur.com/izC5Hke.png + :target: https://i.imgur.com/izC5Hke.png + :alt: eclipse-15 + IMPORTANT: Again we use a folder inside the src-folder -![eclipse-16](https://i.imgur.com/UR8S3I8.png) + +.. image:: https://i.imgur.com/UR8S3I8.png + :target: https://i.imgur.com/UR8S3I8.png + :alt: eclipse-16 + IMPORTANT: Use as new project folder the location of the folder we cloned. -![eclipse-17](https://i.imgur.com/aMu1nNZ.png) + +.. image:: https://i.imgur.com/aMu1nNZ.png + :target: https://i.imgur.com/aMu1nNZ.png + :alt: eclipse-17 + Now we see all 4 Projects in the Project-Explorer view. -![eclipse-18](https://i.imgur.com/36zbuUx.png) + +.. image:: https://i.imgur.com/36zbuUx.png + :target: https://i.imgur.com/36zbuUx.png + :alt: eclipse-18 + If we click in the top-right-corner of the Project-Explorer view we can change the Project-Presentation to Hirachical view. Now it looks like a ROS-2 project as it is on hard-drive. But this view is not good, as the linkage to Egit gets lost. So use the Flat Project-Presentation. The Egit linkage is good if you want to see e.g. which author wrote which code-line, etc. -![eclipse-19](https://i.imgur.com/vOhRUGB.png) + +.. image:: https://i.imgur.com/vOhRUGB.png + :target: https://i.imgur.com/vOhRUGB.png + :alt: eclipse-19 We go to "C/C++ build"-section and put "ament" into "Build command" -![eclipse-26](https://i.imgur.com/vXhRwEb.png) + +.. image:: https://i.imgur.com/vXhRwEb.png + :target: https://i.imgur.com/vXhRwEb.png + :alt: eclipse-26 + Go to "Behavior" tab and unselect "clean" and put "build" into Build textbox. -![eclipse-26](https://i.imgur.com/4CegjkC.png) + +.. image:: https://i.imgur.com/4CegjkC.png + :target: https://i.imgur.com/4CegjkC.png + :alt: eclipse-26 + Before you can "Build Project" you need to close eclipse. Open a shell and source the ROS-2 setup.bash file, then cd into the directory of the eclipse project (here: /home/ubu/rviz2_ws/rviz2_ws) and start eclipse from inside this directory. -![eclipse-27](https://i.imgur.com/ZyPGJLa.png) + +.. image:: https://i.imgur.com/ZyPGJLa.png + :target: https://i.imgur.com/ZyPGJLa.png + :alt: eclipse-27 + Now you can use code-completion, egit annotations, eclipse C/C++ Tools, etc. -![eclipse-28](https://i.imgur.com/YUEH3lM.png) - +.. image:: https://i.imgur.com/YUEH3lM.png + :target: https://i.imgur.com/YUEH3lM.png + :alt: eclipse-28 + -## Eclipse-indexer +:raw-html-m2r:`` + +Eclipse-indexer +--------------- If you open e.g. main.cpp of rviz2 you will perhaps see alot of "unresolved inclusion".You need todo the following that they disappear and that right-click->Open-Declaration will fully work. Goto Project->Properties->C++General->Path-and-Symbols and to tab References and select "ros2_ws". IMPORTANT: If you have different eclipse-workspaces for ros2_ws and e.g. rviz2_ws, you can add your ros2_ws the same way as later the qt5 directory get added. Hint: Just add the src folder, e.g. /home/ros/ros2_ws/ros2_ws/src not the build and install directories. -![eclipse-28](https://i.imgur.com/mp9Pgzu.png) + +.. image:: https://i.imgur.com/mp9Pgzu.png + :target: https://i.imgur.com/mp9Pgzu.png + :alt: eclipse-28 + Goto C/C++-General->Path-and-Symbols to tab "Source locations" and click on "Link folder". There choose the location of qt5 includes. -![eclipse-28](https://i.imgur.com/TYgDACE.png) + +.. image:: https://i.imgur.com/TYgDACE.png + :target: https://i.imgur.com/TYgDACE.png + :alt: eclipse-28 then you see something like the next image. You could also add "excludes" (filters) to the added source locations, so that some directories dont get indexed. Its good for the "build" and "install" directories in the rviz2_ws which include duplicate headers. -![eclipse-28](https://i.imgur.com/nv9tEAP.png) + +.. image:: https://i.imgur.com/nv9tEAP.png + :target: https://i.imgur.com/nv9tEAP.png + :alt: eclipse-28 Goto C++General->Preprocessor includes, select CDT-GCC-Built-in-compiler-settings[shared] and enter into the text-box "command to get compiler specs" the following -``` --std=c++14 -``` -![eclipse-28](https://i.imgur.com/9DNXpDD.png) +.. code-block:: + + -std=c++14 + + +.. image:: https://i.imgur.com/9DNXpDD.png + :target: https://i.imgur.com/9DNXpDD.png + :alt: eclipse-28 + Then goto "C/C++-General->Indexer" and select the following in the image. E.g "index unused headers as c files" is to resolve e.g. QApplication, because the QApplication headers content is only "#include "qapplication.h". -![eclipse-28](https://i.imgur.com/Wxeheak.png) + +.. image:: https://i.imgur.com/Wxeheak.png + :target: https://i.imgur.com/Wxeheak.png + :alt: eclipse-28 After running the indexer (which happens later,so you will see this also later), you can see what it added -![eclipse-28](https://i.imgur.com/xtxZ4bg.png) + +.. image:: https://i.imgur.com/xtxZ4bg.png + :target: https://i.imgur.com/xtxZ4bg.png + :alt: eclipse-28 + After that right-click on the rviz2 project and select "Indexer->Rebuild", after that, you see down-right a progress, you will see that it can resolve all includes. -![eclipse-28](https://i.imgur.com/uGZaHau.png) - +.. image:: https://i.imgur.com/uGZaHau.png + :target: https://i.imgur.com/uGZaHau.png + :alt: eclipse-28 + + +:raw-html-m2r:`` -## Debugging with eclipse +Debugging with eclipse +---------------------- Goto "C/C++-Build" and add to the build command -``` --DCMAKE_BUILD_TYPE=Debug -``` -![eclipse-28](https://i.imgur.com/KXFYDHg.png) + +.. code-block:: + + -DCMAKE_BUILD_TYPE=Debug + + +.. image:: https://i.imgur.com/KXFYDHg.png + :target: https://i.imgur.com/KXFYDHg.png + :alt: eclipse-28 + Then in eclipse goto "Run->Debug Configurations" and add the following and click on "Debug" -![eclipse-28](https://i.imgur.com/ywzAxUP.png) + +.. image:: https://i.imgur.com/ywzAxUP.png + :target: https://i.imgur.com/ywzAxUP.png + :alt: eclipse-28 diff --git a/Features.md b/Features.md deleted file mode 100644 index f3e8d1a4390..00000000000 --- a/Features.md +++ /dev/null @@ -1,27 +0,0 @@ -# ROS 2 Feature Status - -The features listed below are available in the current ROS 2 release. -Unless otherwise specified, the features are available for all supported platforms (Ubuntu 18.04, OS X 10.12.x, Windows 10), DDS implementations (eProsima Fast RTPS, RTI Connext and PrismTech Opensplice) and programming language client libraries (C++ and Python). -For planned future development, see the [Roadmap](Roadmap.md). - -| Functionality | Link | Fine print | -| --- | --- | --- | -| Discovery, transport and serialization over DDS | [Article](http://design.ros2.org/articles/ros_on_dds.html) | | -| Support for multiple DDS implementations, chosen at runtime | [Tutorial](DDS-and-ROS-middleware-implementations.md) | Currently eProsima Fast RTPS, RTI Connext and PrismTech Opensplice are fully supported. | -| Common core client library that is wrapped by language-specific libraries | [Tutorial](ROS 2 Client Libraries.md) | | -| Publish/subscribe over topics | [Sample code](https://github.com/ros2/examples), [Article](http://design.ros2.org/articles/topic_and_service_names.html) | | -| Clients and services | [Sample code](https://github.com/ros2/examples) | | -| Set/retrieve parameters | [Sample code](https://github.com/ros2/demos/tree/0.5.1/demo_nodes_cpp/src/parameters) | Parameters not yet available in `rcl`/Python. | -| ROS 1 - ROS 2 communication bridge | [Tutorial](https://github.com/ros2/ros1_bridge/blob/master/README.md) | Available for topics and services, not yet available for actions. | -| Quality of service settings for handling non-ideal networks | [Demo](Quality-Of-Service.md) | | -| Inter- and intra-process communication using the same API | [Demo](Intra-Process-Communication.md) | Currently only in C++. | -| Composition of node components at compile-, link- or `dlopen`-time | [Demo](Composition.md) | Currently only in C++. | -| Support for nodes with managed lifecycles | [Demo](Managed-Nodes.md) | Currently only in C++. | -| DDS-Security support | [Demo](https://github.com/ros2/sros2) | | -| Command-line introspection tools using an extensible framework | [Tutorial](Introspection-with-command-line-tools.md) | | -| Launch system for coordinating multiple nodes | [Tutorial](Launch-system.md) | | -| Namespace support for nodes and topics | [Article](http://design.ros2.org/articles/topic_and_service_names.html) | | -| Static remapping of ROS names | [Tutorial](Node-arguments.md) | | -| Demos of an all-ROS 2 mobile robot | [Demo](https://github.com/ros2/turtlebot2_demo) | | -| Preliminary support for real-time code | [Demo](Real-Time-Programming.md), [demo](Allocator-Template-Tutorial.md) | Linux only. Not available for Fast RTPS. | -| Preliminary support for "bare-metal" microcontrollers | [Wiki](https://github.com/ros2/freertps/wiki)| | diff --git a/Features.rst b/Features.rst new file mode 100644 index 00000000000..06c0bb2e174 --- /dev/null +++ b/Features.rst @@ -0,0 +1,72 @@ + +ROS 2 Feature Status +==================== + +The features listed below are available in the current ROS 2 release. +Unless otherwise specified, the features are available for all supported platforms (Ubuntu 18.04, OS X 10.12.x, Windows 10), DDS implementations (eProsima Fast RTPS, RTI Connext and PrismTech Opensplice) and programming language client libraries (C++ and Python). +For planned future development, see the `Roadmap `. + +.. list-table:: + :header-rows: 1 + + * - Functionality + - Link + - Fine print + * - Discovery, transport and serialization over DDS + - `Article `__ + - + * - Support for multiple DDS implementations, chosen at runtime + - `Tutorial ` + - Currently eProsima Fast RTPS, RTI Connext and PrismTech Opensplice are fully supported. + * - Common core client library that is wrapped by language-specific libraries + - `Tutorial ` + - + * - Publish/subscribe over topics + - `Sample code `__\ , `Article `__ + - + * - Clients and services + - `Sample code `__ + - + * - Set/retrieve parameters + - `Sample code `__ + - Parameters not yet available in ``rcl``\ /Python. + * - ROS 1 - ROS 2 communication bridge + - `Tutorial `__ + - Available for topics and services, not yet available for actions. + * - Quality of service settings for handling non-ideal networks + - `Demo ` + - + * - Inter- and intra-process communication using the same API + - `Demo ` + - Currently only in C++. + * - Composition of node components at compile-, link- or ``dlopen``\ -time + - `Demo ` + - Currently only in C++. + * - Support for nodes with managed lifecycles + - `Demo ` + - Currently only in C++. + * - DDS-Security support + - `Demo `__ + - + * - Command-line introspection tools using an extensible framework + - `Tutorial ` + - + * - Launch system for coordinating multiple nodes + - `Tutorial ` + - + * - Namespace support for nodes and topics + - `Article `__ + - + * - Static remapping of ROS names + - `Tutorial ` + - + * - Demos of an all-ROS 2 mobile robot + - `Demo `__ + - + * - Preliminary support for real-time code + - `Demo `\ , `demo ` + - Linux only. Not available for Fast RTPS. + * - Preliminary support for "bare-metal" microcontrollers + - `Wiki `__ + - + diff --git a/Fedora-Development-Setup.md b/Fedora-Development-Setup.md deleted file mode 100644 index 3ff74a46b79..00000000000 --- a/Fedora-Development-Setup.md +++ /dev/null @@ -1,15 +0,0 @@ -## How to setup the development environment? - -First install a bunch of dependencies: - -``` -$ sudo dnf install cppcheck cmake libXaw-devel opencv-devel poco-devel poco-foundation python3-empy python3-devel python3-nose python3-pip python3-pyparsing python3-pytest python3-pytest-cov python3-pytest-runner python3-setuptools python3-yaml tinyxml-devel eigen3-devel python3-pydocstyle python3-pyflakes python3-coverage python3-mock python3-pep8 uncrustify python3-argcomplete python3-flake8 python3-flake8-import-order asio-devel tinyxml2-devel libyaml-devel -``` - -Then install vcstool from pip: - -``` -$ pip3 install vcstool -``` - -With this done, you can follow the rest of the [instructions](Linux-Development-Setup#get-ros-20-code.md) to fetch and build ROS2. \ No newline at end of file diff --git a/Fedora-Development-Setup.rst b/Fedora-Development-Setup.rst new file mode 100644 index 00000000000..ec4775c839e --- /dev/null +++ b/Fedora-Development-Setup.rst @@ -0,0 +1,17 @@ + +How to setup the development environment? +----------------------------------------- + +First install a bunch of dependencies: + +.. code-block:: + + $ sudo dnf install cppcheck cmake libXaw-devel opencv-devel poco-devel poco-foundation python3-empy python3-devel python3-nose python3-pip python3-pyparsing python3-pytest python3-pytest-cov python3-pytest-runner python3-setuptools python3-yaml tinyxml-devel eigen3-devel python3-pydocstyle python3-pyflakes python3-coverage python3-mock python3-pep8 uncrustify python3-argcomplete python3-flake8 python3-flake8-import-order asio-devel tinyxml2-devel libyaml-devel + +Then install vcstool from pip: + +.. code-block:: + + $ pip3 install vcstool + +With this done, you can follow the rest of the `instructions ` to fetch and build ROS2. diff --git a/Install-Connext-Security-Plugins.md b/Install-Connext-Security-Plugins.rst similarity index 54% rename from Install-Connext-Security-Plugins.md rename to Install-Connext-Security-Plugins.rst index e2f916044cb..b6daa3dc0c6 100644 --- a/Install-Connext-Security-Plugins.md +++ b/Install-Connext-Security-Plugins.rst @@ -1,5 +1,7 @@ -# Installing Connext security plugins + +Installing Connext security plugins +=================================== The Connext DDS Security Plugins are typically paired with tools for system debugging, integration, and testing, including a launcher/installer facility. Connext DDS Security Plugins are installed using the RTI Launcher utility. -These tools and plugins are available from RTI; visit [https://www.rti.com/ncl](https://www.rti.com/ncl) to learn more. \ No newline at end of file +These tools and plugins are available from RTI; visit `https://www.rti.com/ncl `__ to learn more. diff --git a/Installation.md b/Installation.md deleted file mode 100644 index 7c84563e62b..00000000000 --- a/Installation.md +++ /dev/null @@ -1,19 +0,0 @@ -# Installation - -## Binary packages - -We provide ROS 2 binary packages for the following platforms: - -* Linux (Ubuntu Xenial(16.04) and Ubuntu Bionic(18.04)) - * [Debian packages](Linux-Install-Debians.md) - * ["fat" archive](Linux-Install-Binary.md) -* [OS X](OSX-Install-Binary.md) -* [Windows](Windows-Install-Binary.md) - -## Building from source - -We support building ROS 2 from source on the following platforms: - -* [Linux](Linux-Development-Setup.md) -* [OS X](OSX-Development-Setup.md) -* [Windows](Windows-Development-Setup.md) diff --git a/Installation.rst b/Installation.rst new file mode 100644 index 00000000000..01333b1061e --- /dev/null +++ b/Installation.rst @@ -0,0 +1,27 @@ + +Installation +============ + +Binary packages +--------------- + +We provide ROS 2 binary packages for the following platforms: + + +* Linux (Ubuntu Xenial(16.04) and Ubuntu Bionic(18.04)) + + * `Debian packages ` + * `"fat" archive ` + +* `OS X ` +* `Windows ` + +Building from source +-------------------- + +We support building ROS 2 from source on the following platforms: + + +* `Linux ` +* `OS X ` +* `Windows ` diff --git a/Intel-ROS2-Projects.md b/Intel-ROS2-Projects.md deleted file mode 100644 index cde24224a99..00000000000 --- a/Intel-ROS2-Projects.md +++ /dev/null @@ -1,16 +0,0 @@ -# Intel ROS2 Projects -Intel® Robotics Open Source Project (Intel® ROS Project) to enable the object detection, 2D location, 3D location and tracking with GPU or [Intel® Movidius™ NCS](https://developer.movidius.com/) optimized deep learning backend, and [Intel® RealSense™](http://www.intel.com/realsense) camera under ROS2 framework. - -## Key Projects -We will work on below ROS2 projects and publish source code at https://github.com/intel/ gradually. -* [ROS2 RealSense Camera](https://github.com/intel/ros2_intel_realsense): ROS2 package for Intel® RealSense™ D400 serial cameras -* [ROS2 Movidius NCS](https://github.com/intel/ros2_intel_movidius_ncs): ROS2 package for object detection with Intel® Movidius™ Neural Computing Stick (NCS). -* [ROS2 Object Messages](https://github.com/intel/ros2_object_msgs): ROS2 messages for object. -* [ROS2 Object Analytics](https://github.com/intel/ros2_object_analytics): ROS2 package for object detection, tracking and 2D/3D localization. -* [ROS2 Message Filters](https://github.com/intel/ros2_message_filters): ROS2 package for message synchronization with time stamp. -* [ROS2 CV Bridge](https://github.com/ros-perception/vision_opencv/tree/ros2/cv_bridge): ROS2 package to bridge with openCV. -* [ROS2 Object Map](https://github.com/intel/ros2_object_map): ROS2 package to mark tag of objects on map when SLAM based on information provided by ROS2 object analytics. -* [ROS2 Moving Object](https://github.com/intel/ros2_moving_object): ROS2 package to provide object motion information (like object velocity on x, y, z axis) based on information provided by ROS2 object analytics. - -## Reference -ROS components at: http://wiki.ros.org/IntelROSProject shows the relationship among those packages, which also applies to ROS2. \ No newline at end of file diff --git a/Intel-ROS2-Projects.rst b/Intel-ROS2-Projects.rst new file mode 100644 index 00000000000..d3155cd43e3 --- /dev/null +++ b/Intel-ROS2-Projects.rst @@ -0,0 +1,25 @@ + +Intel ROS2 Projects +=================== + +Intel® Robotics Open Source Project (Intel® ROS Project) to enable the object detection, 2D location, 3D location and tracking with GPU or `Intel® Movidius™ NCS `__ optimized deep learning backend, and `Intel® RealSense™ `__ camera under ROS2 framework. + +Key Projects +------------ + +We will work on below ROS2 projects and publish source code at https://github.com/intel/ gradually. + + +* `ROS2 RealSense Camera `__\ : ROS2 package for Intel® RealSense™ D400 serial cameras +* `ROS2 Movidius NCS `__\ : ROS2 package for object detection with Intel® Movidius™ Neural Computing Stick (NCS). +* `ROS2 Object Messages `__\ : ROS2 messages for object. +* `ROS2 Object Analytics `__\ : ROS2 package for object detection, tracking and 2D/3D localization. +* `ROS2 Message Filters `__\ : ROS2 package for message synchronization with time stamp. +* `ROS2 CV Bridge `__\ : ROS2 package to bridge with openCV. +* `ROS2 Object Map `__\ : ROS2 package to mark tag of objects on map when SLAM based on information provided by ROS2 object analytics. +* `ROS2 Moving Object `__\ : ROS2 package to provide object motion information (like object velocity on x, y, z axis) based on information provided by ROS2 object analytics. + +Reference +--------- + +ROS components at: http://wiki.ros.org/IntelROSProject shows the relationship among those packages, which also applies to ROS2. diff --git a/Intra-Process-Communication.md b/Intra-Process-Communication.md deleted file mode 100644 index 359992be477..00000000000 --- a/Intra-Process-Communication.md +++ /dev/null @@ -1,416 +0,0 @@ -# Intra-process communication - -## Background - -ROS applications typically consist of a composition of individual "nodes" which perform narrow tasks and are decoupled from other parts of the system. -This promotes fault isolation, faster development, modularity, and code reuse, but it often comes at the cost of performance. -After ROS 1 was initially developed, the need for efficient composition of nodes became obvious and Nodelets were developed. -In ROS 2 we aim to improve on the design of Nodelets by addressing some fundamental problems that required restructuring of nodes. - -In this demo we'll be highlighting how nodes can be composed manually, by defining the nodes separately but combining them in different process layouts without changing the node's code or limiting its abilities. - -## Build the demos - -These demos should work on any of the three major OSs (Windows, Mac, or Linux). -Some of them do require OpenCV to have been installed. - -### Using the pre-built binaries - -If you've installed the binaries, simply source the ROS 2 setup file and then skip down to any of the individual demos to see how to run them. - -### Building from source - -Make sure you have OpenCV installed and then follow the source instructions. -You can find the from source instructions linked from the main [ros2 installation page](Installation.md). -Once built source the setup file and continue down to one of the specific demos to read about them and for instructions on how to run them. - -## Running and understanding the demos - -There are a few different demos: some are toy problems designed to highlight features of the intra process communications functionality and some are end to end examples which use OpenCV and demonstrate the ability to recombine nodes into different configurations. - -### The two node pipeline demo - -This demo is designed to show that the intra process publish/subscribe connection can result in zero-copy transport of messages when publishing and subscribing with `std::unique_ptr`s. - -First let's take a look at the source: - -https://github.com/ros2/demos/blob/master/intra_process_demo/src/two_node_pipeline/two_node_pipeline.cpp -```c++ -#include -#include -#include -#include -#include - -#include "rclcpp/rclcpp.hpp" -#include "std_msgs/msg/int32.hpp" - -using namespace std::chrono_literals; - -// Node that produces messages. -struct Producer : public rclcpp::Node -{ - Producer(const std::string & name, const std::string & output) - : Node(name, "", true) - { - // Create a publisher on the output topic. - pub_ = this->create_publisher(output, rmw_qos_profile_default); - std::weak_ptr::type> captured_pub = pub_; - // Create a timer which publishes on the output topic at ~1Hz. - auto callback = [captured_pub]() -> void { - auto pub_ptr = captured_pub.lock(); - if (!pub_ptr) { - return; - } - static int32_t count = 0; - std_msgs::msg::Int32::UniquePtr msg(new std_msgs::msg::Int32()); - msg->data = count++; - printf( - "Published message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, - reinterpret_cast(msg.get())); - pub_ptr->publish(msg); - }; - timer_ = this->create_wall_timer(1s, callback); - } - - rclcpp::Publisher::SharedPtr pub_; - rclcpp::TimerBase::SharedPtr timer_; -}; - -// Node that consumes messages. -struct Consumer : public rclcpp::Node -{ - Consumer(const std::string & name, const std::string & input) - : Node(name, "", true) - { - // Create a subscription on the input topic which prints on receipt of new messages. - sub_ = this->create_subscription( - input, [](std_msgs::msg::Int32::UniquePtr msg) { - printf( - " Received message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, - reinterpret_cast(msg.get())); - }, rmw_qos_profile_default); - } - - rclcpp::Subscription::SharedPtr sub_; -}; - -int main(int argc, char * argv[]) -{ - setvbuf(stdout, NULL, _IONBF, BUFSIZ); - rclcpp::init(argc, argv); - rclcpp::executors::SingleThreadedExecutor executor; - - auto producer = std::make_shared("producer", "number"); - auto consumer = std::make_shared("consumer", "number"); - - executor.add_node(producer); - executor.add_node(consumer); - executor.spin(); - return 0; -} -``` - -As you can see by looking at the `main` function, we have a producer and a consumer node, we add them to a single threaded executor, and then call spin. - -If you look at the "producer" node's implementation in the `Producer` struct, you can see that we have created a publisher which publishes on the "number" topic and a timer which periodically creates a new message, prints out its address in memory and its content's value and then publishes it. - -The "consumer" node is a bit simpler, you can see its implementation in the `Consumer` struct, as it only subscribes to the "number" topic and prints the address and value of the message it receives. - -The expectation is that the producer will print out an address and value and the consumer will print out a matching address and value. -This demonstrates that intra process communication is indeed working and unnecessary copies are avoided, at least for simple graphs. - -Let's run the demo by executing `ros2 run intra_process_demo two_node_pipeline` executable (don't forget to source the setup file first): - -``` -$ ros2 run intra_process_demo two_node_pipeline -Published message with value: 0, and address: 0x7fb02303faf0 -Published message with value: 1, and address: 0x7fb020cf0520 - Received message with value: 1, and address: 0x7fb020cf0520 -Published message with value: 2, and address: 0x7fb020e12900 - Received message with value: 2, and address: 0x7fb020e12900 -Published message with value: 3, and address: 0x7fb020cf0520 - Received message with value: 3, and address: 0x7fb020cf0520 -Published message with value: 4, and address: 0x7fb020e12900 - Received message with value: 4, and address: 0x7fb020e12900 -Published message with value: 5, and address: 0x7fb02303cea0 - Received message with value: 5, and address: 0x7fb02303cea0 -[...] -``` - -One thing you'll notice is that the messages tick along at about one per second. -This is because we told the timer to fire at about once per second. - -Also you may have noticed that the first message (with value `0`) does not have a corresponding "Received message ..." line. -This is because publish/subscribe is "best effort" and we do not have any "latching" like behavior enabled. -This means that if the publisher publishes a message before the subscription has been established, the subscription will not receive that message. -This race condition can result in the first few messages being lost. -In this case, since they only come once per second, usually only the first message is lost. - -Finally, you can see that "Published message..." and "Received message ..." lines with the same value also have the same address. -This shows that the address of the message being received is the same as the one that was published and that it is not a copy. -This is because we're publishing and subscribing with `std::unique_ptr`s which allow ownership of a message to be moved around the system safely. -You can also publish and subscribe with `const &` and `std::shared_ptr`, but zero-copy will not occur in that case. - -### The cyclic pipeline demo - -This demo is similar to the previous one, but instead of the producer creating a new message for each iteration, this demo only ever uses one message instance. -This is achieved by creating a cycle in the graph and "kicking off" communication by externally making one of the nodes publish before spinning the executor: - -https://github.com/ros2/demos/blob/master/intra_process_demo/src/cyclic_pipeline/cyclic_pipeline.cpp -```c++ -#include -#include -#include -#include -#include - -#include "rclcpp/rclcpp.hpp" -#include "std_msgs/msg/int32.hpp" - -using namespace std::chrono_literals; - -// This node receives an Int32, waits 1 second, then increments and sends it. -struct IncrementerPipe : public rclcpp::Node -{ - IncrementerPipe(const std::string & name, const std::string & in, const std::string & out) - : Node(name, "", true) - { - // Create a publisher on the output topic. - pub = this->create_publisher(out, rmw_qos_profile_default); - std::weak_ptr::type> captured_pub = pub; - // Create a subscription on the input topic. - sub = this->create_subscription( - in, [captured_pub](std_msgs::msg::Int32::UniquePtr msg) { - auto pub_ptr = captured_pub.lock(); - if (!pub_ptr) { - return; - } - printf( - "Received message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, - reinterpret_cast(msg.get())); - printf(" sleeping for 1 second...\n"); - if (!rclcpp::sleep_for(1s)) { - return; // Return if the sleep failed (e.g. on ctrl-c). - } - printf(" done.\n"); - msg->data++; // Increment the message's data. - printf( - "Incrementing and sending with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, - reinterpret_cast(msg.get())); - pub_ptr->publish(msg); // Send the message along to the output topic. - }, rmw_qos_profile_default); - } - - rclcpp::Publisher::SharedPtr pub; - rclcpp::Subscription::SharedPtr sub; -}; - -int main(int argc, char * argv[]) -{ - setvbuf(stdout, NULL, _IONBF, BUFSIZ); - rclcpp::init(argc, argv); - rclcpp::executors::SingleThreadedExecutor executor; - - // Create a simple loop by connecting the in and out topics of two IncrementerPipe's. - // The expectation is that the address of the message being passed between them never changes. - auto pipe1 = std::make_shared("pipe1", "topic1", "topic2"); - auto pipe2 = std::make_shared("pipe2", "topic2", "topic1"); - rclcpp::sleep_for(1s); // Wait for subscriptions to be established to avoid race conditions. - // Publish the first message (kicking off the cycle). - std::unique_ptr msg(new std_msgs::msg::Int32()); - msg->data = 42; - printf( - "Published first message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, - reinterpret_cast(msg.get())); - pipe1->pub->publish(msg); - - executor.add_node(pipe1); - executor.add_node(pipe2); - executor.spin(); - return 0; -} -``` - -Unlike the previous demo, this demo uses only one Node, instantiated twice with different names and configurations. -The graph ends up being `pipe1` -> `pipe2` -> `pipe1` ... in a loop. - -The line `pipe1->pub->publish(msg);` kicks the process off, but from then on the messages are passed back and forth between the nodes by each one calling publish within its own subscription callback. - -The expectation here is that the nodes pass the message back and forth, once a second, incrementing the value of the message each time. -Because the message is being published and subscribed to as a `unique_ptr` the same message created at the beginning is continuously used. - -To test those expectations, let's run it: - -``` -% ros2 run intra_process_demo cyclic_pipeline -Published first message with value: 42, and address: 0x7fd2ce0a2bc0 -Received message with value: 42, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... - done. -Incrementing and sending with value: 43, and address: 0x7fd2ce0a2bc0 -Received message with value: 43, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... - done. -Incrementing and sending with value: 44, and address: 0x7fd2ce0a2bc0 -Received message with value: 44, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... - done. -Incrementing and sending with value: 45, and address: 0x7fd2ce0a2bc0 -Received message with value: 45, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... - done. -Incrementing and sending with value: 46, and address: 0x7fd2ce0a2bc0 -Received message with value: 46, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... - done. -Incrementing and sending with value: 47, and address: 0x7fd2ce0a2bc0 -Received message with value: 47, and address: 0x7fd2ce0a2bc0 - sleeping for 1 second... -[...] -``` - -You should see ever increasing numbers on each iteration, starting with 42... because 42, and the whole time it reuses the same message, as demonstrated by the pointer addresses which do not change, which avoids unnecessary copies. - -### The image pipeline demo - -In this demo we'll use OpenCV to capture, annotate, and then view images. - -Note for OS X users: If you these examples do not work or you receive an error like `ddsi_conn_write failed -1` then you'll need to increase your system wide UDP packet size: - -``` -$ sudo sysctl -w net.inet.udp.recvspace=209715 -$ sudo sysctl -w net.inet.udp.maxdgram=65500 -``` - -These changes will not persist after a reboot. - -#### Simple pipeline - -First we'll have a pipeline of three nodes, arranged as such: `camera_node` -> `watermark_node` -> `image_view_node` - -The `camera_node` reads from camera device `0` on your computer, writes some information on the image and publishes it. -The `watermark_node` subscribes to the output of the `camera_node` and adds more text before publishing it too. -Finally, the `image_view_node` subscribes to the output of the `watermark_node`, writes more text to the image and then visualizes it with `cv::imshow`. - -In each node the address of the message which is being sent, or which has been received, or both, is written to the image. -The watermark and image view nodes are designed to modify the image without copying it and so the addresses imprinted on the image should all be the same as long as the nodes are in the same process and the graph remains organized in a pipeline as sketched above. - -**Note:** On some systems (we've seen it happen on Linux), the address printed to the screen might not change. -This is because the same unique pointer is being reused. -In this situation, the pipeline is still running. - -Let's run the demo by executing the following executable: -``` -ros2 run intra_process_demo image_pipeline_all_in_one -``` -You should see something like this: - -![](http://i.imgur.com/tqiIVgT.png) - -You can pause the rendering of the image by pressing the spacebar and you can resume by pressing the spacebar again. -You can also press `q` or `ESC` to exit. - -If you pause the image viewer, you should be able to compare the addresses written on the image and see that they are the same. - -#### Pipeline with two image viewers - -Now let's look at an example just the one above, except it has two image view nodes. -All the nodes are still in the same process, but now two image view windows should show up. (Note for OS X users: your image view windows might be on top of each other.) -Let's run it with the command -``` -ros2 run intra_process_demo image_pipeline_with_two_image_view -``` - -![](http://i.imgur.com/iLIT02t.png) - -Just like the last example, you can pause the rendering with the spacebar and continue by pressing the spacebar a second time. You can stop the updating to inspect the pointers written to the screen. - -As you can see in the example image above, we have one image with all of the pointers the same and then another image with the same pointers as the first image for the first two entries, but the last pointer on the second image is different. To understand why this is happening consider the graph's topology: - -`camera_node` -> `watermark_node` -> `image_view_node` - \-> `image_view_node2` - -The link between the `camera_node` and the `watermark_node` can use the same pointer without copying because there is only one intra process subscription to which the message should be delivered. But for the link between the `watermark_node` and the two image view nodes the relationship is one to many, so if the image view nodes were using `unique_ptr` callbacks then it would be impossible to deliver the ownership of the same pointer to both. It can be, however, delivered to one of them. Which one would get the original pointer is not defined, but instead is simply the last to be delivered. - -Note that the image view nodes are not subscribed with `unique_ptr` callbacks. Instead they are subscribed with `const shared_ptr`s. This means the system could have delivered the same `shared_ptr` to both callbacks. Currently the intra process system is not that intelligent and so it stores the message internally as a `unique_ptr` and copies it into a `shared_ptr` for each callback until the last one. On the last callback, regardless of the type, the ownership is transferred out of intra process storage and, in the case of the image view, the ownership is moved into a new `shared_ptr` and delivered. Thus, one of the image view nodes gets a copy and the other gets the original. - -#### Pipeline with interprocess viewer - -One other important thing to get right is to avoid interruption of the intra process zero-copy behavior when interprocess subscriptions are made. To test this we can run the first image pipeline demo, `image_pipeline_all_in_one`, and then run an instance of the stand alone `image_view_node` (don't forget to prefix them with `ros2 run intra_process_demo` in the terminal). This will look something like this: - -![](http://i.imgur.com/MoWRH1u.png) - -It's hard to pause both images at the same time so the images may not line up, but the important thing to notice is that the `image_pipeline_all_in_one` image view shows the same address for each step. This means that the intra process zero-copy is preserved even when an external view is subscribed as well. You can also see that the interprocess image view has different process IDs for the first two lines of text and the process ID of the standalone image viewer in the third line of text. - -## Looking forward - -These demos are the foundation for some cool new features on which we're actively working, but right now some things are missing. - -### Room for Improvement - -Let's start by looking at what we at OSRF know we can do better or differently and move on from there. - -#### Intra Process Manager Storage - -At the core of the intra process implementation is something called the intra process manager. It is the shared state between nodes (not necessarily global) which facilitates intra process communication. The intra process manager has a lot of room for improvement, but one thing on our short list is to have it be more intelligent about how to store the user's data internally. In the example with two image view nodes all in the same process, we could have delivered the user's provided pointer to both image view nodes as copies of a single `shared_ptr`. This is possible only because of the intra process graph's structure, but given any relationship of a publisher to one or more intra process subscriptions there should be a preferred solution. - -For example, imagine if there was a publisher connected to three intra process subscriptions where one was subscribed as a `unique_ptr` and the other two were subscribed as a `shared_ptr`. If you store the the message as a `unique_ptr` then you must make a copy for each of the `shared_ptr` but you can deliver to the `unique_ptr` callback without a copy. But if you instead stored the message as a `shared_ptr` then you give that `shared_ptr` to the two `shared_ptr` callbacks and make one copy for the `unique_ptr` callback, which would save on copies. In both cases we've assumed that only one copy of the message should be stored, i.e. we will not store a `unique_ptr` of the message as well as a `shared_ptr` copy. There is a performance trade-off when decided whether to make those copies or not, so one thing to figure out moving forward is how and when to expose this trade-off to the developer. - -This problem gets more interesting when we start doing Type Masquerading :smile:, which we'll talk about below. - -#### Avoiding Unnecessary Interprocess Publishes - -Currently we're relying on the middleware, the DDS vendor, to avoid publishing to the wire unnecessarily, but no matter what we have to give the middleware a copy of the user's message. We could avoid this copy given to the system if we could know if it is needed. We can do this currently by checking to see if there are any non intra process subscriptions currently attached to the publisher. The problem with this becomes apparent when we go to implement latching, which we'll see more about below. - -#### Avoiding Memory Allocation - -In other parts of the system we've worked really hard to allow users to avoid memory allocation. This has performance benefits and may be required for real-time or embedded scenarios. We cannot currently do that with intra process. Mostly this is because we haven't had time to figure out the right interfaces, but the general problem is that if a message needs to be delivered to more than one subscription, or if the user gives us a `const &` or `const shared_ptr` when publishing, we need to make a copy. And the destination of the copy is currently created using `new` and is not configurable. We expect to resolve that in the future. - -#### Performance, Performance, Performance - -This is a very rough first draft. There is a lot of room for improvement, even beyond what has been enumerated above. We'll start to improve performance as we dig into the details of the system, build up a better understanding of exactly what our middleware vendors are doing, and try alternative strategies for implementing intra process. - -### What's Missing - -Aforementioned are some things we can improve with what's already there. But there are also some things we'd like to add on top of this that are pretty interesting and some things that are just necessary. - -#### Latching - -We haven't fully implemented the concept of latching yet, but it's very likely we'll need to adjust the implementation of the intra process manager to account for the fact that late intra process subscriptions should be delivered to as well. There are several options on how to do that, and we'll do some testing and figure out what to do in the near future. - -#### Beyond Pub/Sub - -We've not done any of this with Services, Parameters, or Actions, but we will. - -#### Type Masquerading - -This is one of the coolest upcoming features that we didn't get to in this demo. -Imagine the image pipeline demo above, but rather than passing `sensor_msgs/Image`s around, you're publishing and subscribing to `cv::Mat` objects. This exists in ROS 1, see: http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes - -In ROS 1, this is accomplished by serializing/deserializing the third party type when handling it. This means that with intra process you'll be serializing when passing it between nodelets. But in ROS 2 we want to do it in the most performant way possible. Similar to how these demos have been demonstrating that an instance of a message can be used through the whole pipeline in certain cases, we'd like to do the same with third party types. So conceivably you could have the image pipeline with a single `cv::Mat` which never gets copied by the middleware. To do this requires some additional intelligence in the intra process manager, but we've already got a design and some proof of concepts in the works. - -Given these features, hopefully there will come a point where you can trust the middleware to handle your data as efficiently as is possible. This will allow you to write performant algorithms without sacrificing modularity or introspection! - -#### Tooling - -One of the sticking points of Nodelets in ROS 1 was the complexity of defining, building, and using them. -We've not tackled that problem yet, but we are working on it. We've got a port of class loader (https://github.com/ros/class_loader/tree/ros2) and pluginlib (https://github.com/ros/pluginlib/tree/ros2) for ROS 2, but we only have prototypes of the CMake infrastructure which will help users build and run their nodes. Here's a sketch of the design we expect: - -```cmake -add_node(my_node src/my_node.cpp) -target_link_libraries(my_node ${external_dependency_LIBRARIES} ...) -``` - -We'll provide an interface similar to CMake's `add_executable` or `add_library`. This doesn't preclude the idea of providing a more automatic solution a la `ament_cmake_auto`. - -This simple CMake entry will generate a few things: - -- A marker file used to discover the node by pluginlib. -- A shared library for your node. -- An executable for your node. - - The executable can run the node in its own process, or serve as a proxy while the node runs in a different container. - -We'll also need to develop the container, which can run nodes inside of itself and is controlled externally by ROS primitives like Services. - -We've got a lot of work to do, but hopefully this tutorial gives you a sense of where we're going and what we're trying to do in terms of performance and features. \ No newline at end of file diff --git a/Intra-Process-Communication.rst b/Intra-Process-Communication.rst new file mode 100644 index 00000000000..daa291095f2 --- /dev/null +++ b/Intra-Process-Communication.rst @@ -0,0 +1,459 @@ + +Intra-process communication +=========================== + +Background +---------- + +ROS applications typically consist of a composition of individual "nodes" which perform narrow tasks and are decoupled from other parts of the system. +This promotes fault isolation, faster development, modularity, and code reuse, but it often comes at the cost of performance. +After ROS 1 was initially developed, the need for efficient composition of nodes became obvious and Nodelets were developed. +In ROS 2 we aim to improve on the design of Nodelets by addressing some fundamental problems that required restructuring of nodes. + +In this demo we'll be highlighting how nodes can be composed manually, by defining the nodes separately but combining them in different process layouts without changing the node's code or limiting its abilities. + +Build the demos +--------------- + +These demos should work on any of the three major OSs (Windows, Mac, or Linux). +Some of them do require OpenCV to have been installed. + +Using the pre-built binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you've installed the binaries, simply source the ROS 2 setup file and then skip down to any of the individual demos to see how to run them. + +Building from source +^^^^^^^^^^^^^^^^^^^^ + +Make sure you have OpenCV installed and then follow the source instructions. +You can find the from source instructions linked from the main `ros2 installation page `. +Once built source the setup file and continue down to one of the specific demos to read about them and for instructions on how to run them. + +Running and understanding the demos +----------------------------------- + +There are a few different demos: some are toy problems designed to highlight features of the intra process communications functionality and some are end to end examples which use OpenCV and demonstrate the ability to recombine nodes into different configurations. + +The two node pipeline demo +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This demo is designed to show that the intra process publish/subscribe connection can result in zero-copy transport of messages when publishing and subscribing with ``std::unique_ptr``\ s. + +First let's take a look at the source: + +https://github.com/ros2/demos/blob/master/intra_process_demo/src/two_node_pipeline/two_node_pipeline.cpp + +.. code-block:: c++ + + #include + #include + #include + #include + #include + + #include "rclcpp/rclcpp.hpp" + #include "std_msgs/msg/int32.hpp" + + using namespace std::chrono_literals; + + // Node that produces messages. + struct Producer : public rclcpp::Node + { + Producer(const std::string & name, const std::string & output) + : Node(name, "", true) + { + // Create a publisher on the output topic. + pub_ = this->create_publisher(output, rmw_qos_profile_default); + std::weak_ptr::type> captured_pub = pub_; + // Create a timer which publishes on the output topic at ~1Hz. + auto callback = [captured_pub]() -> void { + auto pub_ptr = captured_pub.lock(); + if (!pub_ptr) { + return; + } + static int32_t count = 0; + std_msgs::msg::Int32::UniquePtr msg(new std_msgs::msg::Int32()); + msg->data = count++; + printf( + "Published message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, + reinterpret_cast(msg.get())); + pub_ptr->publish(msg); + }; + timer_ = this->create_wall_timer(1s, callback); + } + + rclcpp::Publisher::SharedPtr pub_; + rclcpp::TimerBase::SharedPtr timer_; + }; + + // Node that consumes messages. + struct Consumer : public rclcpp::Node + { + Consumer(const std::string & name, const std::string & input) + : Node(name, "", true) + { + // Create a subscription on the input topic which prints on receipt of new messages. + sub_ = this->create_subscription( + input, [](std_msgs::msg::Int32::UniquePtr msg) { + printf( + " Received message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, + reinterpret_cast(msg.get())); + }, rmw_qos_profile_default); + } + + rclcpp::Subscription::SharedPtr sub_; + }; + + int main(int argc, char * argv[]) + { + setvbuf(stdout, NULL, _IONBF, BUFSIZ); + rclcpp::init(argc, argv); + rclcpp::executors::SingleThreadedExecutor executor; + + auto producer = std::make_shared("producer", "number"); + auto consumer = std::make_shared("consumer", "number"); + + executor.add_node(producer); + executor.add_node(consumer); + executor.spin(); + return 0; + } + +As you can see by looking at the ``main`` function, we have a producer and a consumer node, we add them to a single threaded executor, and then call spin. + +If you look at the "producer" node's implementation in the ``Producer`` struct, you can see that we have created a publisher which publishes on the "number" topic and a timer which periodically creates a new message, prints out its address in memory and its content's value and then publishes it. + +The "consumer" node is a bit simpler, you can see its implementation in the ``Consumer`` struct, as it only subscribes to the "number" topic and prints the address and value of the message it receives. + +The expectation is that the producer will print out an address and value and the consumer will print out a matching address and value. +This demonstrates that intra process communication is indeed working and unnecessary copies are avoided, at least for simple graphs. + +Let's run the demo by executing ``ros2 run intra_process_demo two_node_pipeline`` executable (don't forget to source the setup file first): + +.. code-block:: + + $ ros2 run intra_process_demo two_node_pipeline + Published message with value: 0, and address: 0x7fb02303faf0 + Published message with value: 1, and address: 0x7fb020cf0520 + Received message with value: 1, and address: 0x7fb020cf0520 + Published message with value: 2, and address: 0x7fb020e12900 + Received message with value: 2, and address: 0x7fb020e12900 + Published message with value: 3, and address: 0x7fb020cf0520 + Received message with value: 3, and address: 0x7fb020cf0520 + Published message with value: 4, and address: 0x7fb020e12900 + Received message with value: 4, and address: 0x7fb020e12900 + Published message with value: 5, and address: 0x7fb02303cea0 + Received message with value: 5, and address: 0x7fb02303cea0 + [...] + +One thing you'll notice is that the messages tick along at about one per second. +This is because we told the timer to fire at about once per second. + +Also you may have noticed that the first message (with value ``0``\ ) does not have a corresponding "Received message ..." line. +This is because publish/subscribe is "best effort" and we do not have any "latching" like behavior enabled. +This means that if the publisher publishes a message before the subscription has been established, the subscription will not receive that message. +This race condition can result in the first few messages being lost. +In this case, since they only come once per second, usually only the first message is lost. + +Finally, you can see that "Published message..." and "Received message ..." lines with the same value also have the same address. +This shows that the address of the message being received is the same as the one that was published and that it is not a copy. +This is because we're publishing and subscribing with ``std::unique_ptr``\ s which allow ownership of a message to be moved around the system safely. +You can also publish and subscribe with ``const &`` and ``std::shared_ptr``\ , but zero-copy will not occur in that case. + +The cyclic pipeline demo +^^^^^^^^^^^^^^^^^^^^^^^^ + +This demo is similar to the previous one, but instead of the producer creating a new message for each iteration, this demo only ever uses one message instance. +This is achieved by creating a cycle in the graph and "kicking off" communication by externally making one of the nodes publish before spinning the executor: + +https://github.com/ros2/demos/blob/master/intra_process_demo/src/cyclic_pipeline/cyclic_pipeline.cpp + +.. code-block:: c++ + + #include + #include + #include + #include + #include + + #include "rclcpp/rclcpp.hpp" + #include "std_msgs/msg/int32.hpp" + + using namespace std::chrono_literals; + + // This node receives an Int32, waits 1 second, then increments and sends it. + struct IncrementerPipe : public rclcpp::Node + { + IncrementerPipe(const std::string & name, const std::string & in, const std::string & out) + : Node(name, "", true) + { + // Create a publisher on the output topic. + pub = this->create_publisher(out, rmw_qos_profile_default); + std::weak_ptr::type> captured_pub = pub; + // Create a subscription on the input topic. + sub = this->create_subscription( + in, [captured_pub](std_msgs::msg::Int32::UniquePtr msg) { + auto pub_ptr = captured_pub.lock(); + if (!pub_ptr) { + return; + } + printf( + "Received message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, + reinterpret_cast(msg.get())); + printf(" sleeping for 1 second...\n"); + if (!rclcpp::sleep_for(1s)) { + return; // Return if the sleep failed (e.g. on ctrl-c). + } + printf(" done.\n"); + msg->data++; // Increment the message's data. + printf( + "Incrementing and sending with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, + reinterpret_cast(msg.get())); + pub_ptr->publish(msg); // Send the message along to the output topic. + }, rmw_qos_profile_default); + } + + rclcpp::Publisher::SharedPtr pub; + rclcpp::Subscription::SharedPtr sub; + }; + + int main(int argc, char * argv[]) + { + setvbuf(stdout, NULL, _IONBF, BUFSIZ); + rclcpp::init(argc, argv); + rclcpp::executors::SingleThreadedExecutor executor; + + // Create a simple loop by connecting the in and out topics of two IncrementerPipe's. + // The expectation is that the address of the message being passed between them never changes. + auto pipe1 = std::make_shared("pipe1", "topic1", "topic2"); + auto pipe2 = std::make_shared("pipe2", "topic2", "topic1"); + rclcpp::sleep_for(1s); // Wait for subscriptions to be established to avoid race conditions. + // Publish the first message (kicking off the cycle). + std::unique_ptr msg(new std_msgs::msg::Int32()); + msg->data = 42; + printf( + "Published first message with value: %d, and address: 0x%" PRIXPTR "\n", msg->data, + reinterpret_cast(msg.get())); + pipe1->pub->publish(msg); + + executor.add_node(pipe1); + executor.add_node(pipe2); + executor.spin(); + return 0; + } + +Unlike the previous demo, this demo uses only one Node, instantiated twice with different names and configurations. +The graph ends up being ``pipe1`` -> ``pipe2`` -> ``pipe1`` ... in a loop. + +The line ``pipe1->pub->publish(msg);`` kicks the process off, but from then on the messages are passed back and forth between the nodes by each one calling publish within its own subscription callback. + +The expectation here is that the nodes pass the message back and forth, once a second, incrementing the value of the message each time. +Because the message is being published and subscribed to as a ``unique_ptr`` the same message created at the beginning is continuously used. + +To test those expectations, let's run it: + +.. code-block:: + + % ros2 run intra_process_demo cyclic_pipeline + Published first message with value: 42, and address: 0x7fd2ce0a2bc0 + Received message with value: 42, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + done. + Incrementing and sending with value: 43, and address: 0x7fd2ce0a2bc0 + Received message with value: 43, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + done. + Incrementing and sending with value: 44, and address: 0x7fd2ce0a2bc0 + Received message with value: 44, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + done. + Incrementing and sending with value: 45, and address: 0x7fd2ce0a2bc0 + Received message with value: 45, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + done. + Incrementing and sending with value: 46, and address: 0x7fd2ce0a2bc0 + Received message with value: 46, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + done. + Incrementing and sending with value: 47, and address: 0x7fd2ce0a2bc0 + Received message with value: 47, and address: 0x7fd2ce0a2bc0 + sleeping for 1 second... + [...] + +You should see ever increasing numbers on each iteration, starting with 42... because 42, and the whole time it reuses the same message, as demonstrated by the pointer addresses which do not change, which avoids unnecessary copies. + +The image pipeline demo +^^^^^^^^^^^^^^^^^^^^^^^ + +In this demo we'll use OpenCV to capture, annotate, and then view images. + +Note for OS X users: If you these examples do not work or you receive an error like ``ddsi_conn_write failed -1`` then you'll need to increase your system wide UDP packet size: + +.. code-block:: + + $ sudo sysctl -w net.inet.udp.recvspace=209715 + $ sudo sysctl -w net.inet.udp.maxdgram=65500 + +These changes will not persist after a reboot. + +Simple pipeline +~~~~~~~~~~~~~~~ + +First we'll have a pipeline of three nodes, arranged as such: ``camera_node`` -> ``watermark_node`` -> ``image_view_node`` + +The ``camera_node`` reads from camera device ``0`` on your computer, writes some information on the image and publishes it. +The ``watermark_node`` subscribes to the output of the ``camera_node`` and adds more text before publishing it too. +Finally, the ``image_view_node`` subscribes to the output of the ``watermark_node``\ , writes more text to the image and then visualizes it with ``cv::imshow``. + +In each node the address of the message which is being sent, or which has been received, or both, is written to the image. +The watermark and image view nodes are designed to modify the image without copying it and so the addresses imprinted on the image should all be the same as long as the nodes are in the same process and the graph remains organized in a pipeline as sketched above. + +**Note:** On some systems (we've seen it happen on Linux), the address printed to the screen might not change. +This is because the same unique pointer is being reused. +In this situation, the pipeline is still running. + +Let's run the demo by executing the following executable: + +.. code-block:: + + ros2 run intra_process_demo image_pipeline_all_in_one + +You should see something like this: + + +.. image:: http://i.imgur.com/tqiIVgT.png + :target: http://i.imgur.com/tqiIVgT.png + :alt: + + +You can pause the rendering of the image by pressing the spacebar and you can resume by pressing the spacebar again. +You can also press ``q`` or ``ESC`` to exit. + +If you pause the image viewer, you should be able to compare the addresses written on the image and see that they are the same. + +Pipeline with two image viewers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now let's look at an example just the one above, except it has two image view nodes. +All the nodes are still in the same process, but now two image view windows should show up. (Note for OS X users: your image view windows might be on top of each other.) +Let's run it with the command + +.. code-block:: + + ros2 run intra_process_demo image_pipeline_with_two_image_view + + +.. image:: http://i.imgur.com/iLIT02t.png + :target: http://i.imgur.com/iLIT02t.png + :alt: + + +Just like the last example, you can pause the rendering with the spacebar and continue by pressing the spacebar a second time. You can stop the updating to inspect the pointers written to the screen. + +As you can see in the example image above, we have one image with all of the pointers the same and then another image with the same pointers as the first image for the first two entries, but the last pointer on the second image is different. To understand why this is happening consider the graph's topology: + +``camera_node`` -> ``watermark_node`` -> ``image_view_node`` + -> ``image_view_node2`` + +The link between the ``camera_node`` and the ``watermark_node`` can use the same pointer without copying because there is only one intra process subscription to which the message should be delivered. But for the link between the ``watermark_node`` and the two image view nodes the relationship is one to many, so if the image view nodes were using ``unique_ptr`` callbacks then it would be impossible to deliver the ownership of the same pointer to both. It can be, however, delivered to one of them. Which one would get the original pointer is not defined, but instead is simply the last to be delivered. + +Note that the image view nodes are not subscribed with ``unique_ptr`` callbacks. Instead they are subscribed with ``const shared_ptr``\ s. This means the system could have delivered the same ``shared_ptr`` to both callbacks. Currently the intra process system is not that intelligent and so it stores the message internally as a ``unique_ptr`` and copies it into a ``shared_ptr`` for each callback until the last one. On the last callback, regardless of the type, the ownership is transferred out of intra process storage and, in the case of the image view, the ownership is moved into a new ``shared_ptr`` and delivered. Thus, one of the image view nodes gets a copy and the other gets the original. + +Pipeline with interprocess viewer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One other important thing to get right is to avoid interruption of the intra process zero-copy behavior when interprocess subscriptions are made. To test this we can run the first image pipeline demo, ``image_pipeline_all_in_one``\ , and then run an instance of the stand alone ``image_view_node`` (don't forget to prefix them with ``ros2 run intra_process_demo`` in the terminal). This will look something like this: + + +.. image:: http://i.imgur.com/MoWRH1u.png + :target: http://i.imgur.com/MoWRH1u.png + :alt: + + +It's hard to pause both images at the same time so the images may not line up, but the important thing to notice is that the ``image_pipeline_all_in_one`` image view shows the same address for each step. This means that the intra process zero-copy is preserved even when an external view is subscribed as well. You can also see that the interprocess image view has different process IDs for the first two lines of text and the process ID of the standalone image viewer in the third line of text. + +Looking forward +--------------- + +These demos are the foundation for some cool new features on which we're actively working, but right now some things are missing. + +Room for Improvement +^^^^^^^^^^^^^^^^^^^^ + +Let's start by looking at what we at OSRF know we can do better or differently and move on from there. + +Intra Process Manager Storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +At the core of the intra process implementation is something called the intra process manager. It is the shared state between nodes (not necessarily global) which facilitates intra process communication. The intra process manager has a lot of room for improvement, but one thing on our short list is to have it be more intelligent about how to store the user's data internally. In the example with two image view nodes all in the same process, we could have delivered the user's provided pointer to both image view nodes as copies of a single ``shared_ptr``. This is possible only because of the intra process graph's structure, but given any relationship of a publisher to one or more intra process subscriptions there should be a preferred solution. + +For example, imagine if there was a publisher connected to three intra process subscriptions where one was subscribed as a ``unique_ptr`` and the other two were subscribed as a ``shared_ptr``. If you store the the message as a ``unique_ptr`` then you must make a copy for each of the ``shared_ptr`` but you can deliver to the ``unique_ptr`` callback without a copy. But if you instead stored the message as a ``shared_ptr`` then you give that ``shared_ptr`` to the two ``shared_ptr`` callbacks and make one copy for the ``unique_ptr`` callback, which would save on copies. In both cases we've assumed that only one copy of the message should be stored, i.e. we will not store a ``unique_ptr`` of the message as well as a ``shared_ptr`` copy. There is a performance trade-off when decided whether to make those copies or not, so one thing to figure out moving forward is how and when to expose this trade-off to the developer. + +This problem gets more interesting when we start doing Type Masquerading :smile:, which we'll talk about below. + +Avoiding Unnecessary Interprocess Publishes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently we're relying on the middleware, the DDS vendor, to avoid publishing to the wire unnecessarily, but no matter what we have to give the middleware a copy of the user's message. We could avoid this copy given to the system if we could know if it is needed. We can do this currently by checking to see if there are any non intra process subscriptions currently attached to the publisher. The problem with this becomes apparent when we go to implement latching, which we'll see more about below. + +Avoiding Memory Allocation +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In other parts of the system we've worked really hard to allow users to avoid memory allocation. This has performance benefits and may be required for real-time or embedded scenarios. We cannot currently do that with intra process. Mostly this is because we haven't had time to figure out the right interfaces, but the general problem is that if a message needs to be delivered to more than one subscription, or if the user gives us a ``const &`` or ``const shared_ptr`` when publishing, we need to make a copy. And the destination of the copy is currently created using ``new`` and is not configurable. We expect to resolve that in the future. + +Performance, Performance, Performance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is a very rough first draft. There is a lot of room for improvement, even beyond what has been enumerated above. We'll start to improve performance as we dig into the details of the system, build up a better understanding of exactly what our middleware vendors are doing, and try alternative strategies for implementing intra process. + +What's Missing +^^^^^^^^^^^^^^ + +Aforementioned are some things we can improve with what's already there. But there are also some things we'd like to add on top of this that are pretty interesting and some things that are just necessary. + +Latching +~~~~~~~~ + +We haven't fully implemented the concept of latching yet, but it's very likely we'll need to adjust the implementation of the intra process manager to account for the fact that late intra process subscriptions should be delivered to as well. There are several options on how to do that, and we'll do some testing and figure out what to do in the near future. + +Beyond Pub/Sub +~~~~~~~~~~~~~~ + +We've not done any of this with Services, Parameters, or Actions, but we will. + +Type Masquerading +~~~~~~~~~~~~~~~~~ + +This is one of the coolest upcoming features that we didn't get to in this demo. +Imagine the image pipeline demo above, but rather than passing ``sensor_msgs/Image``\ s around, you're publishing and subscribing to ``cv::Mat`` objects. This exists in ROS 1, see: http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes + +In ROS 1, this is accomplished by serializing/deserializing the third party type when handling it. This means that with intra process you'll be serializing when passing it between nodelets. But in ROS 2 we want to do it in the most performant way possible. Similar to how these demos have been demonstrating that an instance of a message can be used through the whole pipeline in certain cases, we'd like to do the same with third party types. So conceivably you could have the image pipeline with a single ``cv::Mat`` which never gets copied by the middleware. To do this requires some additional intelligence in the intra process manager, but we've already got a design and some proof of concepts in the works. + +Given these features, hopefully there will come a point where you can trust the middleware to handle your data as efficiently as is possible. This will allow you to write performant algorithms without sacrificing modularity or introspection! + +Tooling +~~~~~~~ + +One of the sticking points of Nodelets in ROS 1 was the complexity of defining, building, and using them. +We've not tackled that problem yet, but we are working on it. We've got a port of class loader (https://github.com/ros/class_loader/tree/ros2) and pluginlib (https://github.com/ros/pluginlib/tree/ros2) for ROS 2, but we only have prototypes of the CMake infrastructure which will help users build and run their nodes. Here's a sketch of the design we expect: + +.. code-block:: cmake + + add_node(my_node src/my_node.cpp) + target_link_libraries(my_node ${external_dependency_LIBRARIES} ...) + +We'll provide an interface similar to CMake's ``add_executable`` or ``add_library``. This doesn't preclude the idea of providing a more automatic solution a la ``ament_cmake_auto``. + +This simple CMake entry will generate a few things: + + +* A marker file used to discover the node by pluginlib. +* A shared library for your node. +* An executable for your node. + + * The executable can run the node in its own process, or serve as a proxy while the node runs in a different container. + +We'll also need to develop the container, which can run nodes inside of itself and is controlled externally by ROS primitives like Services. + +We've got a lot of work to do, but hopefully this tutorial gives you a sense of where we're going and what we're trying to do in terms of performance and features. diff --git a/Introspection-with-command-line-tools.md b/Introspection-with-command-line-tools.md deleted file mode 100644 index 44332fe1b34..00000000000 --- a/Introspection-with-command-line-tools.md +++ /dev/null @@ -1,63 +0,0 @@ -# Overview - -ROS 2 includes a suite of command-line tools for introspecting a ROS 2 system. - -## Usage -The main entry point for the tools is the command `ros2`, which itself has various sub-commands for introspecting and working with nodes, topics, services, and more. - -To see all available sub-commands run: - -``` -ros2 --help -``` - -Examples of sub-commands that are available include: -- daemon: Introspect/configure the ROS 2 daemon -- launch: Run a launch file -- lifecycle: Introspect/manage nodes with managed lifecycles -- msg: Introspect `msg` types -- node: Introspect ROS nodes -- param: Introspect/configure parameters on a node -- pkg: Introspect ROS packages -- run: Run ROS nodes -- security: Configure security settings -- service: Introspect/call ROS services -- srv: Introspect `srv` types -- topic: Introspect/publish ROS topics - -## Example - -To produce the typical talker-listener example using command-line tools, the `topic` sub-command can be used to publish and echo messages on a topic. - -Publish messages in one terminal with: -``` -$ ros2 topic pub /chatter std_msgs/String "data: Hello world" -publisher: beginning loop -publishing std_msgs.msg.String(data='Hello world') - -publishing std_msgs.msg.String(data='Hello world') -``` - -Echo messages received in another terminal with: -``` -$ ros2 topic echo /chatter -data: Hello world - -data: Hello world -``` - -## Behind the scenes - -ROS 2 uses a distributed discovery process for nodes to connect to each other. -As this process purposefully does not use a centralized discovery mechanism (like the ROS Master in ROS 1), it can take time for ROS nodes to discover all other participants in the ROS graph. -Because of this, there is a long-running daemon in the background that stores information about the ROS graph to provide faster responses to queries, e.g. the list of node names. - -The daemon is automatically started when the relevant command-line tools are used for the first time. -You can run `ros2 daemon --help` for more options for interacting with the daemon. - -## Implementation - -The source code for the `ros2` command is available at https://github.com/ros2/ros2cli - -The `ros2` tool has been implemented as a framework that can be extended via plugins. -For example, [the `sros2` package](https://github.com/ros2/sros2) provides a `security` sub-command that is automatically detected by the `ros2` tool if the `sros2` package is installed. diff --git a/Introspection-with-command-line-tools.rst b/Introspection-with-command-line-tools.rst new file mode 100644 index 00000000000..7462e78fcd4 --- /dev/null +++ b/Introspection-with-command-line-tools.rst @@ -0,0 +1,74 @@ + +Overview +======== + +ROS 2 includes a suite of command-line tools for introspecting a ROS 2 system. + +Usage +----- + +The main entry point for the tools is the command ``ros2``\ , which itself has various sub-commands for introspecting and working with nodes, topics, services, and more. + +To see all available sub-commands run: + +.. code-block:: + + ros2 --help + +Examples of sub-commands that are available include: + + +* daemon: Introspect/configure the ROS 2 daemon +* launch: Run a launch file +* lifecycle: Introspect/manage nodes with managed lifecycles +* msg: Introspect ``msg`` types +* node: Introspect ROS nodes +* param: Introspect/configure parameters on a node +* pkg: Introspect ROS packages +* run: Run ROS nodes +* security: Configure security settings +* service: Introspect/call ROS services +* srv: Introspect ``srv`` types +* topic: Introspect/publish ROS topics + +Example +------- + +To produce the typical talker-listener example using command-line tools, the ``topic`` sub-command can be used to publish and echo messages on a topic. + +Publish messages in one terminal with: + +.. code-block:: + + $ ros2 topic pub /chatter std_msgs/String "data: Hello world" + publisher: beginning loop + publishing std_msgs.msg.String(data='Hello world') + + publishing std_msgs.msg.String(data='Hello world') + +Echo messages received in another terminal with: + +.. code-block:: + + $ ros2 topic echo /chatter + data: Hello world + + data: Hello world + +Behind the scenes +----------------- + +ROS 2 uses a distributed discovery process for nodes to connect to each other. +As this process purposefully does not use a centralized discovery mechanism (like the ROS Master in ROS 1), it can take time for ROS nodes to discover all other participants in the ROS graph. +Because of this, there is a long-running daemon in the background that stores information about the ROS graph to provide faster responses to queries, e.g. the list of node names. + +The daemon is automatically started when the relevant command-line tools are used for the first time. +You can run ``ros2 daemon --help`` for more options for interacting with the daemon. + +Implementation +-------------- + +The source code for the ``ros2`` command is available at https://github.com/ros2/ros2cli + +The ``ros2`` tool has been implemented as a framework that can be extended via plugins. +For example, `the ``sros2`` package `__ provides a ``security`` sub-command that is automatically detected by the ``ros2`` tool if the ``sros2`` package is installed. diff --git a/Launch-system.md b/Launch-system.md deleted file mode 100644 index b3711dd7e4c..00000000000 --- a/Launch-system.md +++ /dev/null @@ -1,34 +0,0 @@ -# The ROS 2 Launch System - -The launch system in ROS 2 is responsible for helping the user describe the configuration of their system and then execute it as described. -The configuration of the system includes what programs to run, where to run them, what arguments to pass them, and ROS specific conventions which make it easy to reuse components throughout the system by giving them each different configurations. -It is also responsible for monitoring the state of the processes launched, and reporting and/or reacting to changes in the state of those processes. - -The ROS 2 Bouncy release includes a framework in which launch files, written in Python, can start and stop different nodes as well as trigger and act on various events. -The package providing this framework is `launch_ros`, which uses the non-ROS-specific `launch` framework underneath. - -The [design document (in review)](https://github.com/ros2/design/pull/163) details the goal of the design of ROS 2's launch system (not all functionality is currently available). -## Example of ROS 2 launch concepts - -The launch file in [this example](https://github.com/ros2/launch/blob/master/launch_ros/examples/lifecycle_pub_sub_launch.py) launches two nodes, one of which is a node with a [managed lifecycle](Managed-Nodes.md) (a "lifecycle node"). -Lifecycle nodes launched through `launch_ros` automatically emit _events_ when they transition between states. -The events can then be acted on through the launch framework, e.g. by emitting other events (such as requesting another state transition, which lifecycle nodes launched through `launch_ros` automatically have event handlers for) or triggering other _actions_ (e.g. starting another node). - -In the aforementioned example, various transition requests are requested of the `talker` lifecycle node, and its transition events are reacted to by, for example, launching a `listener` node when the lifecycle talker reaches the appropriate state. - -## Usage - -While launch files can be written as standalone scripts, the typical usage in ROS is to have launch files invoked by ROS 2 tools. - -For example, [this launch file](https://github.com/ros2/demos/blob/master/demo_nodes_cpp/launch/services/add_two_ints.launch.py) has been designed such that it can be invoked by `ros2 launch`: - -```bash -ros2 launch demo_nodes_cpp add_two_ints.launch.py -``` - -## Documentation - -[The `launch` documentation](https://github.com/ros2/launch/blob/master/launch/doc/source/architecture.rst) provides more details on concepts that are also used in `launch_ros`. - -Additional documentation/examples of capabilities are forthcoming. -See [the source code](https://github.com/ros2/launch) in the meantime. \ No newline at end of file diff --git a/Launch-system.rst b/Launch-system.rst new file mode 100644 index 00000000000..14173c9eb70 --- /dev/null +++ b/Launch-system.rst @@ -0,0 +1,40 @@ + +The ROS 2 Launch System +======================= + +The launch system in ROS 2 is responsible for helping the user describe the configuration of their system and then execute it as described. +The configuration of the system includes what programs to run, where to run them, what arguments to pass them, and ROS specific conventions which make it easy to reuse components throughout the system by giving them each different configurations. +It is also responsible for monitoring the state of the processes launched, and reporting and/or reacting to changes in the state of those processes. + +The ROS 2 Bouncy release includes a framework in which launch files, written in Python, can start and stop different nodes as well as trigger and act on various events. +The package providing this framework is ``launch_ros``\ , which uses the non-ROS-specific ``launch`` framework underneath. + +The `design document (in review) `__ details the goal of the design of ROS 2's launch system (not all functionality is currently available). + +Example of ROS 2 launch concepts +-------------------------------- + +The launch file in `this example `__ launches two nodes, one of which is a node with a `managed lifecycle ` (a "lifecycle node"). +Lifecycle nodes launched through ``launch_ros`` automatically emit *events* when they transition between states. +The events can then be acted on through the launch framework, e.g. by emitting other events (such as requesting another state transition, which lifecycle nodes launched through ``launch_ros`` automatically have event handlers for) or triggering other *actions* (e.g. starting another node). + +In the aforementioned example, various transition requests are requested of the ``talker`` lifecycle node, and its transition events are reacted to by, for example, launching a ``listener`` node when the lifecycle talker reaches the appropriate state. + +Usage +----- + +While launch files can be written as standalone scripts, the typical usage in ROS is to have launch files invoked by ROS 2 tools. + +For example, `this launch file `__ has been designed such that it can be invoked by ``ros2 launch``\ : + +.. code-block:: bash + + ros2 launch demo_nodes_cpp add_two_ints.launch.py + +Documentation +------------- + +`The ``launch`` documentation `__ provides more details on concepts that are also used in ``launch_ros``. + +Additional documentation/examples of capabilities are forthcoming. +See `the source code `__ in the meantime. diff --git a/Linux-Development-Setup.md b/Linux-Development-Setup.md deleted file mode 100644 index 167ebfc429a..00000000000 --- a/Linux-Development-Setup.md +++ /dev/null @@ -1,247 +0,0 @@ -# Building ROS 2 on Linux - -## System Requirements - -We support Ubuntu Linux Xenial Xerus 16.04 on 64-bit (until alpha 6 we supported Trusty Tahr 14.04). These instructions should also work for later Ubuntu as well as Debian Stretch, though these are not actively tested or supported. Fedora 26 also works if you follow [alternate](Fedora-Development-Setup.md) instructions, though it is not actively tested or supported. The same goes for [Arch Linux](https://wiki.archlinux.org/index.php/Ros#Ros_2). - -Make sure that you have a locale set which supports `UTF-8` We test with the following settings. -If you are in a minimal environment such as a docker containers the locale may be set to something minimal like POSIX. -To set the locale an example is below. It should be fine if you're using a different UTF-8 supported locale. - -``` -sudo locale-gen en_US en_US.UTF-8 -sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 -export LANG=en_US.UTF-8 -``` - -## System setup - -### Add the ROS 2 apt repository - -First make sure you have the ROS 2 apt repositories added to your system, if not refer to the Setup Sources section of [this guide](Linux-Install-Debians.md#setup-sources) - -### Install development tools and ROS tools - -```bash -sudo apt update && sudo apt install -y \ - build-essential \ - cmake \ - git \ - python3-colcon-common-extensions \ - python3-pip \ - python-rosdep \ - python3-vcstool \ - wget -# install some pip packages needed for testing -sudo -H python3 -m pip install -U \ - argcomplete \ - flake8 \ - flake8-blind-except \ - flake8-builtins \ - flake8-class-newline \ - flake8-comprehensions \ - flake8-deprecated \ - flake8-docstrings \ - flake8-import-order \ - flake8-quotes \ - pytest-repeat \ - pytest-rerunfailures -# [Ubuntu 16.04] install extra packages not available or recent enough on Xenial -python3 -m pip install -U \ - pytest \ - pytest-cov \ - pytest-runner \ - setuptools -# install Fast-RTPS dependencies -sudo apt install --no-install-recommends -y \ - libasio-dev \ - libtinyxml2-dev -``` - -### Get ROS 2.0 code - -Create a workspace and clone all repos: - -``` -mkdir -p ~/ros2_ws/src -cd ~/ros2_ws -wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -vcs import src < ros2.repos -``` - -> Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing `release-latest` in the URL above with `master`. The `release-latest` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also [Maintaining a Source Checkout](Maintaining-a-Source-Checkout.md). - -### Install dependencies using rosdep - -```bash -sudo rosdep init -rosdep update -rosdep install --from-paths src --ignore-src --rosdistro bouncy -y --skip-keys "console_bridge fastcdr fastrtps libopensplice67 rti-connext-dds-5.3.1 urdfdom_headers" -``` - -### Install more DDS implementations (Optional) - -ROS 2.0 builds on top of DDS. -It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. -The repositories you downloaded for ROS 2.0 includes eProsima's Fast RTPS, which is the only bundled vendor. -If you would like to use one of the other vendors you will need to install their software separately before building. -The ROS 2.0 build will automatically build support for vendors that have been installed and sourced correctly. - -By default we include eProsima's FastRTPS in the workspace and it is the default middleware. Detailed instructions for installing other DDS vendors are provided below. - -#### PrismTech OpenSplice Debian Packages built by OSRF - - -``` -sudo apt install libopensplice67 # from repo.ros2.org -``` - -Add this to your `~/.bashrc` - -``` -export OSPL_URI=file:///usr/etc/opensplice/config/ospl.xml -``` - - - -#### RTI Connext (version 5.3.1) - -To use RTI Connext you will need to have obtained a license from RTI. -Add the following line to your `.bashrc` file pointing to your copy of the license. - -``` -export RTI_LICENSE_FILE=path/to/rti_license.dat -``` - -#### Debian packages provided in the ROS 2 apt repositories - -You can install a Debian package of RTI Connext availabel on the ROS 2 apt repositories. -You will need to accept a license from RTI. - -``` -sudo apt install -q -y \ - rti-connext-dds-5.3.1 # from repo.ros2.org -``` - -Source the setup file to set the `NDDSHOME` environment variable. - -``` -cd /opt/rti.com/rti_connext_dds-5.3.1/resource/scripts && source ./rtisetenv_x64Linux3gcc5.4.0.bash; cd - -``` - -Note: when using `zsh` you need to be in the directory of the script when sourcing it to have it work properly - -Now you can build as normal and support for RTI will be built as well. - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - - -### Build the code in the workspace - -Note: to build the ROS 1 bridge, read the [ros1_bridge instructions](https://github.com/ros2/ros1_bridge/blob/master/README.md#build-the-bridge-from-source). - -More info on working with a ROS workspace can be found in [this tutorial](Colcon-Tutorial). - -``` -cd ~/ros2_ws/ -colcon build --symlink-install -``` - -Note: if you are having trouble compiling all examples and this is preventing you from completing a successful build, you can use `AMENT_IGNORE` in the same manner as [`CATKIN_IGNORE`](https://github.com/ros-infrastructure/rep/blob/master/rep-0128.rst) to ignore the subtree or remove the folder from the workspace. -Take for instance: you would like to avoid installing the large OpenCV library. -Well then simply `$ touch AMENT_IGNORE` in the `cam2image` demo directory to leave it out of the build process. - -Optionally install all packages into a combined directory (rather than each package in a separate subdirectory). -On Windows due to limitations of the length of environment variables you should use this option when building workspaces with many (~ >> 100 packages). - -``` -colcon build --symlink-install --merge-install -``` - -Afterwards source the `local_setup.*` from the `install` folder. - -### Try some examples - -In one terminal, source the setup file and then run a `talker`: -``` -. ~/ros2_ws/install/local_setup.bash -ros2 run demo_nodes_cpp talker -``` -In another terminal source the setup file and then run a `listener`: -``` -. ~/ros2_ws/install/local_setup.bash -ros2 run demo_nodes_py listener -``` -You should see the `talker` saying that it's `Publishing` messages and the `listener` saying `I heard` those messages. -Hooray! - -See the [demos](Tutorials) for other things to try. - -## Alternate compilers - -Using a different compiler besides gcc to compile ROS 2 is easy. If you set the environment variables `CC` and `CXX` to executables for a working C and C++ compiler, respectively, and retrigger CMake configuration (by using `--force-cmake-config` or by deleting the packages you want to be affected), CMake will reconfigure and use the different compiler. - -### Clang - -To configure CMake to detect and use Clang: - -``` -sudo apt install clang -export CC=clang -export CXX=clang++ -colcon build --cmake-force-configure -``` - -TODO: using ThreadSanitizer, MemorySanitizer - -## Troubleshooting - -### Internal compiler error - -If you experience an ICE when trying to compile on a memory constrained platform like a Raspberry PI you might want to build single threaded (prefix the build invocation with `MAKEFLAGS=-j1`). - -### Out of memory - -The `ros1_bridge` in its current form requires 4Gb of free RAM to compile. -If you don't have that amount of RAM available it's suggested to use `AMENT_IGNORE` in that folder and skip its compilation. - -### Multiple Host Interference - -If you're running multiple instances on the same network you may get interference. -To avoid this you can set the environment variable `ROS_DOMAIN_ID` to a different integer, the default is zero. -This will define the DDS domain id for your system. -Note that if you are using the OpenSplice DDS implementation you will also need to update the OpenSplice configuration file accordingly. The location of the configuration file is referenced in the `OSPL_URI` environment variable. diff --git a/Linux-Development-Setup.rst b/Linux-Development-Setup.rst new file mode 100644 index 00000000000..3959e27fd3f --- /dev/null +++ b/Linux-Development-Setup.rst @@ -0,0 +1,280 @@ + +Building ROS 2 on Linux +======================= + +System Requirements +------------------- + +We support Ubuntu Linux Xenial Xerus 16.04 on 64-bit (until alpha 6 we supported Trusty Tahr 14.04). These instructions should also work for later Ubuntu as well as Debian Stretch, though these are not actively tested or supported. Fedora 26 also works if you follow `alternate ` instructions, though it is not actively tested or supported. The same goes for `Arch Linux `__. + +Make sure that you have a locale set which supports ``UTF-8`` We test with the following settings. +If you are in a minimal environment such as a docker containers the locale may be set to something minimal like POSIX. +To set the locale an example is below. It should be fine if you're using a different UTF-8 supported locale. + +.. code-block:: + + sudo locale-gen en_US en_US.UTF-8 + sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + export LANG=en_US.UTF-8 + +System setup +------------ + +Add the ROS 2 apt repository +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First make sure you have the ROS 2 apt repositories added to your system, if not refer to the Setup Sources section of `this guide ` + +Install development tools and ROS tools +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + sudo apt update && sudo apt install -y \ + build-essential \ + cmake \ + git \ + python3-colcon-common-extensions \ + python3-pip \ + python-rosdep \ + python3-vcstool \ + wget + # install some pip packages needed for testing + sudo -H python3 -m pip install -U \ + argcomplete \ + flake8 \ + flake8-blind-except \ + flake8-builtins \ + flake8-class-newline \ + flake8-comprehensions \ + flake8-deprecated \ + flake8-docstrings \ + flake8-import-order \ + flake8-quotes \ + pytest-repeat \ + pytest-rerunfailures + # [Ubuntu 16.04] install extra packages not available or recent enough on Xenial + python3 -m pip install -U \ + pytest \ + pytest-cov \ + pytest-runner \ + setuptools + # install Fast-RTPS dependencies + sudo apt install --no-install-recommends -y \ + libasio-dev \ + libtinyxml2-dev + +Get ROS 2.0 code +^^^^^^^^^^^^^^^^ + +Create a workspace and clone all repos: + +.. code-block:: + + mkdir -p ~/ros2_ws/src + cd ~/ros2_ws + wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos + vcs import src < ros2.repos + +.. + + Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing ``release-latest`` in the URL above with ``master``. The ``release-latest`` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also `Maintaining a Source Checkout `. + + +Install dependencies using rosdep +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + sudo rosdep init + rosdep update + rosdep install --from-paths src --ignore-src --rosdistro bouncy -y --skip-keys "console_bridge fastcdr fastrtps libopensplice67 rti-connext-dds-5.3.1 urdfdom_headers" + +Install more DDS implementations (Optional) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ROS 2.0 builds on top of DDS. +It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. +The repositories you downloaded for ROS 2.0 includes eProsima's Fast RTPS, which is the only bundled vendor. +If you would like to use one of the other vendors you will need to install their software separately before building. +The ROS 2.0 build will automatically build support for vendors that have been installed and sourced correctly. + +By default we include eProsima's FastRTPS in the workspace and it is the default middleware. Detailed instructions for installing other DDS vendors are provided below. + +PrismTech OpenSplice Debian Packages built by OSRF +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: + + sudo apt install libopensplice67 # from repo.ros2.org + +Add this to your ``~/.bashrc`` + +.. code-block:: + + export OSPL_URI=file:///usr/etc/opensplice/config/ospl.xml + + +.. raw:: html + + + + + +RTI Connext (version 5.3.1) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use RTI Connext you will need to have obtained a license from RTI. +Add the following line to your ``.bashrc`` file pointing to your copy of the license. + +.. code-block:: + + export RTI_LICENSE_FILE=path/to/rti_license.dat + +Debian packages provided in the ROS 2 apt repositories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can install a Debian package of RTI Connext availabel on the ROS 2 apt repositories. +You will need to accept a license from RTI. + +.. code-block:: + + sudo apt install -q -y \ + rti-connext-dds-5.3.1 # from repo.ros2.org + +Source the setup file to set the ``NDDSHOME`` environment variable. + +.. code-block:: + + cd /opt/rti.com/rti_connext_dds-5.3.1/resource/scripts && source ./rtisetenv_x64Linux3gcc5.4.0.bash; cd - + +Note: when using ``zsh`` you need to be in the directory of the script when sourcing it to have it work properly + +Now you can build as normal and support for RTI will be built as well. + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + + +Build the code in the workspace +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Note: to build the ROS 1 bridge, read the `ros1_bridge instructions `__. + +More info on working with a ROS workspace can be found in `this tutorial `. + +.. code-block:: + + cd ~/ros2_ws/ + colcon build --symlink-install + +Note: if you are having trouble compiling all examples and this is preventing you from completing a successful build, you can use ``AMENT_IGNORE`` in the same manner as `\ ``CATKIN_IGNORE`` `__ to ignore the subtree or remove the folder from the workspace. +Take for instance: you would like to avoid installing the large OpenCV library. +Well then simply ``$ touch AMENT_IGNORE`` in the ``cam2image`` demo directory to leave it out of the build process. + +Optionally install all packages into a combined directory (rather than each package in a separate subdirectory). +On Windows due to limitations of the length of environment variables you should use this option when building workspaces with many (~ >> 100 packages). + +.. code-block:: + + colcon build --symlink-install --merge-install + +Afterwards source the ``local_setup.*`` from the ``install`` folder. + +Try some examples +^^^^^^^^^^^^^^^^^ + +In one terminal, source the setup file and then run a ``talker``\ : + +.. code-block:: + + . ~/ros2_ws/install/local_setup.bash + ros2 run demo_nodes_cpp talker + +In another terminal source the setup file and then run a ``listener``\ : + +.. code-block:: + + . ~/ros2_ws/install/local_setup.bash + ros2 run demo_nodes_py listener + +You should see the ``talker`` saying that it's ``Publishing`` messages and the ``listener`` saying ``I heard`` those messages. +Hooray! + +See the `demos ` for other things to try. + +Alternate compilers +------------------- + +Using a different compiler besides gcc to compile ROS 2 is easy. If you set the environment variables ``CC`` and ``CXX`` to executables for a working C and C++ compiler, respectively, and retrigger CMake configuration (by using ``--force-cmake-config`` or by deleting the packages you want to be affected), CMake will reconfigure and use the different compiler. + +Clang +^^^^^ + +To configure CMake to detect and use Clang: + +.. code-block:: + + sudo apt install clang + export CC=clang + export CXX=clang++ + colcon build --cmake-force-configure + +TODO: using ThreadSanitizer, MemorySanitizer + +Troubleshooting +--------------- + +Internal compiler error +^^^^^^^^^^^^^^^^^^^^^^^ + +If you experience an ICE when trying to compile on a memory constrained platform like a Raspberry PI you might want to build single threaded (prefix the build invocation with ``MAKEFLAGS=-j1``\ ). + +Out of memory +^^^^^^^^^^^^^ + +The ``ros1_bridge`` in its current form requires 4Gb of free RAM to compile. +If you don't have that amount of RAM available it's suggested to use ``AMENT_IGNORE`` in that folder and skip its compilation. + +Multiple Host Interference +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you're running multiple instances on the same network you may get interference. +To avoid this you can set the environment variable ``ROS_DOMAIN_ID`` to a different integer, the default is zero. +This will define the DDS domain id for your system. +Note that if you are using the OpenSplice DDS implementation you will also need to update the OpenSplice configuration file accordingly. The location of the configuration file is referenced in the ``OSPL_URI`` environment variable. diff --git a/Linux-Install-Binary.md b/Linux-Install-Binary.md deleted file mode 100644 index c57d77a89ab..00000000000 --- a/Linux-Install-Binary.md +++ /dev/null @@ -1,108 +0,0 @@ -# Installing ROS 2 on Linux - -This page explains how to install ROS 2 on Linux from a pre-built binary package. - -As of Beta 2 there are also [Debian packages](Linux-Install-Debians.md) available. - -## System Requirements - -We support Ubuntu Linux Bionic Beaver (18.04) and Ubuntu Xenial Xerus (16.04) on 64-bit x86 and 64-bit ARM. - -Note: Ardent and beta versions supported Ubuntu Xenial Xerus 16.04. - -## Add the ROS 2 apt repository - -See the [development instructions](Linux-Development-Setup#add-the-ros-2-apt-repository.md). - -## Downloading ROS 2 - -* Go the releases page: https://github.com/ros2/ros2/releases -* Download the latest package for Linux; let's assume that it ends up at `~/Downloads/ros2-bouncy-linux-x86_64.tar.bz2`. - * Note: there may be more than one binary download option which might cause the file name to differ. -* Unpack it: - - mkdir -p ~/ros2_install - cd ~/ros2_install - tar xf ~/Downloads/ros2-bouncy-linux-x86_64.tar.bz2 - -## Installing and initializing rosdep - - sudo apt install -y python-rosdep - rosdep init - rosdep update - -## Installing the missing dependencies - - rosdep install --from-paths ros2-linux/share --ignore-src --rosdistro bouncy -y --skip-keys "console_bridge fastcdr fastrtps libopensplice67 osrf_testing_tools_cpp poco_vendor rmw_connext_cpp rosidl_typesupport_connext_c rosidl_typesupport_connext_cpp rti-connext-dds-5.3.1 tinyxml_vendor tinyxml2_vendor urdfdom urdfdom_headers" - -1. *Optional*: if you want to use the ROS 1<->2 bridge, then you must also install ROS 1. - Follow the normal install instructions: http://wiki.ros.org/kinetic/Installation/Ubuntu - -### Installing the python3 libraries - sudo apt install -y libpython3-dev - -## Install additional DDS implementations (optional) - -ROS 2 builds on top of DDS. -It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. - -The package you downloaded has been built with optional support for multiple vendors: eProsima FastRTPS, Adlink OpenSplice, and (as of ROS 2 Bouncy) RTI Connext as the middleware options. -Run-time support for eProsima's Fast RTPS is included bundled by default. -If you would like to use one of the other vendors you will need to install their software separately. - -### Adlink OpenSplice - -To use OpenSplice you can install a Debian package built by OSRF. - - sudo apt update && sudo apt install -q -y \ - libopensplice67 - -### RTI Connext - -To use RTI Connext you will need to have obtained a license from RTI. -Add the following line to your `.bashrc` file pointing to your copy of the license (and source it). - -``` -export RTI_LICENSE_FILE=path/to/rti_license.dat -``` - -You can install a Debian package of RTI Connext built by OSRF. -You will need to accept a license from RTI. - - sudo apt update && sudo apt install -q -y \ - rti-connext-dds-5.3.1 - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -## Try some examples - -In one terminal, source the setup file and then run a `talker`: - - . ~/ros2_install/ros2-linux/setup.bash - ros2 run demo_nodes_cpp talker -In another terminal source the setup file and then run a `listener`: - - . ~/ros2_install/ros2-linux/setup.bash - ros2 run demo_nodes_cpp listener -You should see the `talker` saying that it's `Publishing` messages and the `listener` saying `I heard` those messages. -Hooray! - -If you have installed support for an optional vendor, see [this page](Working-with-multiple-RMW-implementations.md) for details on how to use that vendor. - -See the [demos](Tutorials.md) for other things to try, including how to [run the talker-listener example in Python](Python-Programming.md). - -### ROS 1 bridge - -If you have ROS 1 installed, you can try the ROS 1 bridge, by first sourcing your ROS 1 setup file; we'll assume that it's `/opt/ros/kinetic/setup.bash`. - -If you haven't already, start a roscore: - - . /opt/ros/kinetic/setup.bash - roscore - -In another terminal, start the bridge: - - . /opt/ros/kinetic/setup.bash - . ~/ros2_install/ros2-linux/setup.bash - ros2 run ros1_bridge dynamic_bridge -For more information on the bridge, read the [tutorial](https://github.com/ros2/ros1_bridge/blob/master/README.md). diff --git a/Linux-Install-Binary.rst b/Linux-Install-Binary.rst new file mode 100644 index 00000000000..b5c047861fd --- /dev/null +++ b/Linux-Install-Binary.rst @@ -0,0 +1,156 @@ + +Installing ROS 2 on Linux +========================= + +This page explains how to install ROS 2 on Linux from a pre-built binary package. + +As of Beta 2 there are also `Debian packages ` available. + +System Requirements +------------------- + +We support Ubuntu Linux Bionic Beaver (18.04) and Ubuntu Xenial Xerus (16.04) on 64-bit x86 and 64-bit ARM. + +Note: Ardent and beta versions supported Ubuntu Xenial Xerus 16.04. + +Add the ROS 2 apt repository +---------------------------- + +See the `development instructions `. + +Downloading ROS 2 +----------------- + + +* Go the releases page: https://github.com/ros2/ros2/releases +* Download the latest package for Linux; let's assume that it ends up at ``~/Downloads/ros2-bouncy-linux-x86_64.tar.bz2``. + + * Note: there may be more than one binary download option which might cause the file name to differ. + +* + Unpack it: + + .. code-block:: + + mkdir -p ~/ros2_install + cd ~/ros2_install + tar xf ~/Downloads/ros2-bouncy-linux-x86_64.tar.bz2 + +Installing and initializing rosdep +---------------------------------- + +.. code-block:: + + sudo apt install -y python-rosdep + rosdep init + rosdep update + + +Installing the missing dependencies +----------------------------------- + +.. code-block:: + + rosdep install --from-paths ros2-linux/share --ignore-src --rosdistro bouncy -y --skip-keys "console_bridge fastcdr fastrtps libopensplice67 osrf_testing_tools_cpp poco_vendor rmw_connext_cpp rosidl_typesupport_connext_c rosidl_typesupport_connext_cpp rti-connext-dds-5.3.1 tinyxml_vendor tinyxml2_vendor urdfdom urdfdom_headers" + + + +#. *Optional*\ : if you want to use the ROS 1<->2 bridge, then you must also install ROS 1. + Follow the normal install instructions: http://wiki.ros.org/kinetic/Installation/Ubuntu + +Installing the python3 libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: + + sudo apt install -y libpython3-dev + + +Install additional DDS implementations (optional) +------------------------------------------------- + +ROS 2 builds on top of DDS. +It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. + +The package you downloaded has been built with optional support for multiple vendors: eProsima FastRTPS, Adlink OpenSplice, and (as of ROS 2 Bouncy) RTI Connext as the middleware options. +Run-time support for eProsima's Fast RTPS is included bundled by default. +If you would like to use one of the other vendors you will need to install their software separately. + +Adlink OpenSplice +^^^^^^^^^^^^^^^^^ + +To use OpenSplice you can install a Debian package built by OSRF. + +.. code-block:: + + sudo apt update && sudo apt install -q -y \ + libopensplice67 + + +RTI Connext +^^^^^^^^^^^ + +To use RTI Connext you will need to have obtained a license from RTI. +Add the following line to your ``.bashrc`` file pointing to your copy of the license (and source it). + +.. code-block:: + + export RTI_LICENSE_FILE=path/to/rti_license.dat + +You can install a Debian package of RTI Connext built by OSRF. +You will need to accept a license from RTI. + +.. code-block:: + + sudo apt update && sudo apt install -q -y \ + rti-connext-dds-5.3.1 + + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +Try some examples +----------------- + +In one terminal, source the setup file and then run a ``talker``\ : + +.. code-block:: + + . ~/ros2_install/ros2-linux/setup.bash + ros2 run demo_nodes_cpp talker + +In another terminal source the setup file and then run a ``listener``\ : + +.. code-block:: + + . ~/ros2_install/ros2-linux/setup.bash + ros2 run demo_nodes_cpp listener + +You should see the ``talker`` saying that it's ``Publishing`` messages and the ``listener`` saying ``I heard`` those messages. +Hooray! + +If you have installed support for an optional vendor, see `this page ` for details on how to use that vendor. + +See the `demos ` for other things to try, including how to `run the talker-listener example in Python `. + +ROS 1 bridge +^^^^^^^^^^^^ + +If you have ROS 1 installed, you can try the ROS 1 bridge, by first sourcing your ROS 1 setup file; we'll assume that it's ``/opt/ros/kinetic/setup.bash``. + +If you haven't already, start a roscore: + +.. code-block:: + + . /opt/ros/kinetic/setup.bash + roscore + + +In another terminal, start the bridge: + +.. code-block:: + + . /opt/ros/kinetic/setup.bash + . ~/ros2_install/ros2-linux/setup.bash + ros2 run ros1_bridge dynamic_bridge + +For more information on the bridge, read the `tutorial `__. diff --git a/Linux-Install-Debians.md b/Linux-Install-Debians.md deleted file mode 100644 index a8622fae45d..00000000000 --- a/Linux-Install-Debians.md +++ /dev/null @@ -1,107 +0,0 @@ -# Installing ROS2 via Debian Packages - -Debian packages for ROS 2 Bouncy (the latest release) are available for Ubuntu Bionic; packages for ROS 2 Ardent are available for Ubuntu Xenial. - -Resources: - - [Jenkins Instance](http://build.ros2.org/) - - [Repositories](http://repo.ros2.org) - - Status Pages: - - ROS 2 Bouncy (Ubuntu Bionic): [amd64](http://repo.ros2.org/status_page/ros_bouncy_default.html), [arm64](http://repo.ros2.org/status_page/ros_bouncy_ubv8.html) - - ROS 2 Ardent (Ubuntu Xenial): [amd64](http://repo.ros2.org/status_page/ros_ardent_default.html), [arm64](http://repo.ros2.org/status_page/ros_ardent_uxv8.html) - -## Setup Sources - -To install the Debian packages you will need to add our Debian repository to your apt sources. -First you will need to authorize our gpg key with apt like this: - -``` -sudo apt update && sudo apt install curl -curl http://repo.ros2.org/repos.key | sudo apt-key add - -``` - -And then add the repository to your sources list: - -``` -sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' -``` - -## Install ROS 2 packages - -First set an environment variable for the ROS 2 release you want to install so it can be used in other commands. - -``` -export ROS_DISTRO=bouncy # or ardent -sudo apt update -``` - -Desktop Install (Recommended): ROS, RViz, demos, tutorials. -``` -sudo apt install ros-$ROS_DISTRO-desktop -``` - -ROS-Base Install (Bare Bones): Communication libraries, message packages, command line tools. No GUI tools. -``` -sudo apt install ros-$ROS_DISTRO-ros-base -``` - -See specific sections below for how to also install the ros1_bridge, TurtleBot packages, or alternative RMW packages. - -## Environment setup - -### (optional) Install argcomplete - -ROS 2 commadline tools use argcomplete to autocompletion. So if you want autocompletion, installing argcomplete is necessary. - -#### Ubuntu 18.04 - -``` -sudo apt install python3-argcomplete -``` - -#### Ubuntu 16.04 (argcomplete >= 0.8.5) - -To install `argcomplete` on Ubuntu 16.04 (Xenial), you'll need to use pip, because the version available through `apt` will not work due to a bug in that version of `argcomplete`: - -``` -sudo apt install python3-pip -sudo pip3 install argcomplete -``` - -### Sourcing the setup script - -Set up your environment by sourcing the following file (you may want to add this to your `.bashrc`). -``` -source /opt/ros/$ROS_DISTRO/setup.bash -``` - -## Installing additional RMW implementations - -By default the RMW implementation `FastRTPS` is used. -If using Ardent OpenSplice is also installed. - -To install support for OpenSplice or RTI Connext on Bouncy: -``` -sudo apt update -sudo apt install ros-$ROS_DISTRO-rmw-opensplice-cpp # for OpenSplice -sudo apt install ros-$ROS_DISTRO-rmw-connext-cpp # for RTI Connext (requires license agreement) -``` - -By setting the environment variable `RMW_IMPLEMENTATION=rmw_opensplice_cpp` you can switch to use OpenSplice instead. -For ROS 2 releases Bouncy and newer, `RMW_IMPLEMENTATION=rmw_connext_cpp` can also be selected to use RTI Connext. - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -## Additional packages using ROS 1 packages - -The `ros1_bridge` as well as the TurtleBot demos are using ROS 1 packages. -To be able to install them please start by adding the ROS 1 sources as documented [here](http://wiki.ros.org/Installation/Ubuntu?distro=melodic). - -If you're using Docker for isolation you can start with the image `ros:melodic` or `osrf/ros:melodic-desktop` (or Kinetic if using Ardent). -This will also avoid the need to setup the ROS sources as they will already be integrated. - -Now you can install the remaining packages: - -``` -sudo apt update -sudo apt install ros-$ROS_DISTRO-ros1-bridge ros-$ROS_DISTRO-turtlebot2-* -``` diff --git a/Linux-Install-Debians.rst b/Linux-Install-Debians.rst new file mode 100644 index 00000000000..0880cae3d9a --- /dev/null +++ b/Linux-Install-Debians.rst @@ -0,0 +1,125 @@ + +Installing ROS2 via Debian Packages +=================================== + +Debian packages for ROS 2 Bouncy (the latest release) are available for Ubuntu Bionic; packages for ROS 2 Ardent are available for Ubuntu Xenial. + +Resources: + + +* `Jenkins Instance `__ +* `Repositories `__ +* Status Pages: + + * ROS 2 Bouncy (Ubuntu Bionic): `amd64 `__\ , `arm64 `__ + * ROS 2 Ardent (Ubuntu Xenial): `amd64 `__\ , `arm64 `__ + +Setup Sources +------------- + +To install the Debian packages you will need to add our Debian repository to your apt sources. +First you will need to authorize our gpg key with apt like this: + +.. code-block:: + + sudo apt update && sudo apt install curl + curl http://repo.ros2.org/repos.key | sudo apt-key add - + +And then add the repository to your sources list: + +.. code-block:: + + sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' + +Install ROS 2 packages +---------------------- + +First set an environment variable for the ROS 2 release you want to install so it can be used in other commands. + +.. code-block:: + + export ROS_DISTRO=bouncy # or ardent + sudo apt update + +Desktop Install (Recommended): ROS, RViz, demos, tutorials. + +.. code-block:: + + sudo apt install ros-$ROS_DISTRO-desktop + +ROS-Base Install (Bare Bones): Communication libraries, message packages, command line tools. No GUI tools. + +.. code-block:: + + sudo apt install ros-$ROS_DISTRO-ros-base + +See specific sections below for how to also install the ros1_bridge, TurtleBot packages, or alternative RMW packages. + +Environment setup +----------------- + +(optional) Install argcomplete +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ROS 2 commadline tools use argcomplete to autocompletion. So if you want autocompletion, installing argcomplete is necessary. + +Ubuntu 18.04 +~~~~~~~~~~~~ + +.. code-block:: + + sudo apt install python3-argcomplete + +Ubuntu 16.04 (argcomplete >= 0.8.5) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To install ``argcomplete`` on Ubuntu 16.04 (Xenial), you'll need to use pip, because the version available through ``apt`` will not work due to a bug in that version of ``argcomplete``\ : + +.. code-block:: + + sudo apt install python3-pip + sudo pip3 install argcomplete + +Sourcing the setup script +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Set up your environment by sourcing the following file (you may want to add this to your ``.bashrc``\ ). + +.. code-block:: + + source /opt/ros/$ROS_DISTRO/setup.bash + +Installing additional RMW implementations +----------------------------------------- + +By default the RMW implementation ``FastRTPS`` is used. +If using Ardent OpenSplice is also installed. + +To install support for OpenSplice or RTI Connext on Bouncy: + +.. code-block:: + + sudo apt update + sudo apt install ros-$ROS_DISTRO-rmw-opensplice-cpp # for OpenSplice + sudo apt install ros-$ROS_DISTRO-rmw-connext-cpp # for RTI Connext (requires license agreement) + +By setting the environment variable ``RMW_IMPLEMENTATION=rmw_opensplice_cpp`` you can switch to use OpenSplice instead. +For ROS 2 releases Bouncy and newer, ``RMW_IMPLEMENTATION=rmw_connext_cpp`` can also be selected to use RTI Connext. + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +Additional packages using ROS 1 packages +---------------------------------------- + +The ``ros1_bridge`` as well as the TurtleBot demos are using ROS 1 packages. +To be able to install them please start by adding the ROS 1 sources as documented `here `__. + +If you're using Docker for isolation you can start with the image ``ros:melodic`` or ``osrf/ros:melodic-desktop`` (or Kinetic if using Ardent). +This will also avoid the need to setup the ROS sources as they will already be integrated. + +Now you can install the remaining packages: + +.. code-block:: + + sudo apt update + sudo apt install ros-$ROS_DISTRO-ros1-bridge ros-$ROS_DISTRO-turtlebot2-* diff --git a/Logging-and-logger-configuration.md b/Logging-and-logger-configuration.md deleted file mode 100644 index 2d7b76af736..00000000000 --- a/Logging-and-logger-configuration.md +++ /dev/null @@ -1,104 +0,0 @@ -# Logging and logger configuration demo - -See [the logging page](Logging) for details on available functionality. - -In this demo, different types of log calls are shown and the severity level of different loggers is configured locally and externally. - -Start the demo with: -``` -ros2 run logging_demo logging_demo_main -``` - -Over time you will see output from various log calls with different properties. -To start with you will only see output from log calls with severity `INFO` and above (`WARN`, `ERROR`, `FATAL`). -Note that the first message will only be logged once, though the line is reached on each iteration, as that is a property of the log call used for that message. - -### Logger level configuration: progammatically - -After 10 iterations the level of the logger will be set to `DEBUG`, which will cause additional messages to be logged. - -Some of these debug messages cause additional functions/expressions to be evaluated, which were previously skipped as `DEBUG` log calls were not enabled. -See [the source code](https://github.com/ros2/demos/blob/master/logging_demo/src/logger_usage_component.cpp) of the demo for further explanation of the calls used, and see the [`rclcpp` logging documentation]() for a full list of supported logging calls. - -### Logger level configuration: externally - -In the future there will be a generalized approach to external configuration of loggers at runtime (similar to how [`rqt_logger_level`](http://wiki.ros.org/rqt_logger_level) in ROS 1 allows logger configuration via remote procedural calls). -**This concept is not yet officially supported in ROS 2.** -In the meantime, this demo provides an **example** service that can be called externally to request configuration of logger levels for known names of loggers in the process. - -The demo previously started is already running this example service. -To set the level of the demo's logger back to `INFO`, call the service with: - -``` -ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: 'logger_usage_demo', level: INFO}" -``` - -This service call will work on any logger that is running in the process provided that you know its name. -This includes the loggers in the ROS 2 core, such as `rcl` (the common client library package). -To enable debug logging for `rcl`, call: - -``` -ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: 'rcl', level: DEBUG}" -``` - -You should see debug output from `rcl` start to show. - -#### Using the logger config component - -The server that responds to the logger configuration requests has been developed as a component so that it may be added to an existing composition-based system. -For example, if you are using [a container to run your nodes](Composition#using-components), to be able to configure your loggers you only need to request that it additionally load the `logging_demo::LoggerConfig` component into the container. - -As an example, if you want to debug the `composition::Talker` demo, you can start the talker as normal with: - -Shell 1: -``` -ros2 run composition api_composition -``` -Shell 2: -``` -ros2 run composition api_composition_cli composition composition::Talker -``` - -And then when you want to enable debug logging, load the `LoggerConfig` component with: - -Shell 2 -``` -ros2 run composition api_composition_cli logging_demo logging_demo::LoggerConfig -``` - -And finally, configure all unset loggers to the debug severity by addressing the empty-named logger. -Note that loggers that have been specifically configured to use a particular severity will not be affected by this call. - -Shell 2: -``` -ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: '', level: DEBUG}" -``` -You should see debug output from any previously unset loggers in the process start to appear, including from the ROS 2 core. - -### Logger level configuration: command line - -As of the Bouncy ROS 2 release, the severity level for loggers that have not had their severity set explicitly can be configured from the command line. -Restart the demo including the following command line argument: - -``` -ros2 run logging_demo logging_demo_main __log_level:=debug -``` - -This configures the default severity for any unset logger to the debug severity level. -You should see debug output from loggers from the demo itself and from the ROS 2 core. - -The ability to configure specific loggers from the command line is forthcoming. - -## Console output formatting - -If you would like more or less verbose formatting, you can use [the `RCUTILS_CONSOLE_OUTPUT_FORMAT` environment variable](Logging#console-output-configuration). -For example, to additionally get the timestamp and location of the log calls, stop the demo and restart it with the environment variable set: -``` -export RCUTILS_CONSOLE_OUTPUT_FORMAT="[{severity} {time}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})" -# Or, on Windows: -# set "RCUTILS_CONSOLE_OUTPUT_FORMAT=[{severity} {time}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})" -ros2 run logging_demo logging_demo_main -``` - -You should see the timestamp in seconds and the function name, filename and line number additionally printed with each message. -_The `time` option is only supported as of the ROS 2 Bouncy release._ diff --git a/Logging-and-logger-configuration.rst b/Logging-and-logger-configuration.rst new file mode 100644 index 00000000000..91a62d0043c --- /dev/null +++ b/Logging-and-logger-configuration.rst @@ -0,0 +1,119 @@ + +Logging and logger configuration demo +===================================== + +See `the logging page ` for details on available functionality. + +In this demo, different types of log calls are shown and the severity level of different loggers is configured locally and externally. + +Start the demo with: + +.. code-block:: + + ros2 run logging_demo logging_demo_main + +Over time you will see output from various log calls with different properties. +To start with you will only see output from log calls with severity ``INFO`` and above (\ ``WARN``\ , ``ERROR``\ , ``FATAL``\ ). +Note that the first message will only be logged once, though the line is reached on each iteration, as that is a property of the log call used for that message. + +Logger level configuration: progammatically +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After 10 iterations the level of the logger will be set to ``DEBUG``\ , which will cause additional messages to be logged. + +Some of these debug messages cause additional functions/expressions to be evaluated, which were previously skipped as ``DEBUG`` log calls were not enabled. +See `the source code `__ of the demo for further explanation of the calls used, and see the `\ ``rclcpp`` logging documentation <>` for a full list of supported logging calls. + +Logger level configuration: externally +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In the future there will be a generalized approach to external configuration of loggers at runtime (similar to how `\ ``rqt_logger_level`` `__ in ROS 1 allows logger configuration via remote procedural calls). +**This concept is not yet officially supported in ROS 2.** +In the meantime, this demo provides an **example** service that can be called externally to request configuration of logger levels for known names of loggers in the process. + +The demo previously started is already running this example service. +To set the level of the demo's logger back to ``INFO``\ , call the service with: + +.. code-block:: + + ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: 'logger_usage_demo', level: INFO}" + +This service call will work on any logger that is running in the process provided that you know its name. +This includes the loggers in the ROS 2 core, such as ``rcl`` (the common client library package). +To enable debug logging for ``rcl``\ , call: + +.. code-block:: + + ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: 'rcl', level: DEBUG}" + +You should see debug output from ``rcl`` start to show. + +Using the logger config component +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The server that responds to the logger configuration requests has been developed as a component so that it may be added to an existing composition-based system. +For example, if you are using `a container to run your nodes `\ , to be able to configure your loggers you only need to request that it additionally load the ``logging_demo::LoggerConfig`` component into the container. + +As an example, if you want to debug the ``composition::Talker`` demo, you can start the talker as normal with: + +Shell 1: + +.. code-block:: + + ros2 run composition api_composition + +Shell 2: + +.. code-block:: + + ros2 run composition api_composition_cli composition composition::Talker + +And then when you want to enable debug logging, load the ``LoggerConfig`` component with: + +Shell 2 + +.. code-block:: + + ros2 run composition api_composition_cli logging_demo logging_demo::LoggerConfig + +And finally, configure all unset loggers to the debug severity by addressing the empty-named logger. +Note that loggers that have been specifically configured to use a particular severity will not be affected by this call. + +Shell 2: + +.. code-block:: + + ros2 service call /config_logger logging_demo/ConfigLogger "{logger_name: '', level: DEBUG}" + +You should see debug output from any previously unset loggers in the process start to appear, including from the ROS 2 core. + +Logger level configuration: command line +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As of the Bouncy ROS 2 release, the severity level for loggers that have not had their severity set explicitly can be configured from the command line. +Restart the demo including the following command line argument: + +.. code-block:: + + ros2 run logging_demo logging_demo_main __log_level:=debug + +This configures the default severity for any unset logger to the debug severity level. +You should see debug output from loggers from the demo itself and from the ROS 2 core. + +The ability to configure specific loggers from the command line is forthcoming. + +Console output formatting +------------------------- + +If you would like more or less verbose formatting, you can use `the ``RCUTILS_CONSOLE_OUTPUT_FORMAT`` environment variable `. +For example, to additionally get the timestamp and location of the log calls, stop the demo and restart it with the environment variable set: + +.. code-block:: + + export RCUTILS_CONSOLE_OUTPUT_FORMAT="[{severity} {time}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})" + # Or, on Windows: + # set "RCUTILS_CONSOLE_OUTPUT_FORMAT=[{severity} {time}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})" + ros2 run logging_demo logging_demo_main + +You should see the timestamp in seconds and the function name, filename and line number additionally printed with each message. +*The ``time`` option is only supported as of the ROS 2 Bouncy release.* diff --git a/Logging.md b/Logging.md deleted file mode 100644 index 9ac4de1dffd..00000000000 --- a/Logging.md +++ /dev/null @@ -1,73 +0,0 @@ -# Logging and logger configuration - -The logging functionality currently supported is: -- Client libraries (`rclcpp` and `rclpy`) using a common logging library to provide: - - Log calls with a variety of filters. - - Hierarchy of loggers. - - Loggers associated with nodes that automatically use the node's name and namespace. -- Console output. - - File output and functionality akin to [`rosout`](http://wiki.ros.org/rosout) for remote consumption of messages is forthcoming. -- Programmatic configuration of logger levels. - - Launch-time configuration of the default logger level is supported; config files and external configuration at run-time is forthcoming. - -## Logger concepts - -Log messages have a severity level associated with them: `DEBUG`, `INFO`, `WARN`, `ERROR` or `FATAL`, in ascending order. - -A logger will only process log messages with severity at or higher than a specified level chosen for the logger. - -Each node (in `rclcpp` and `rclpy`) has a logger associated with it that automatically includes the node's name and namespace. -If the node's name is externally remapped to something other than what is defined in the source code, it will be reflected in the logger name. -Non-node loggers can also be created that use a specific name. - -Logger names represent a hierarchy. -If the level of a logger named "abc.def" is unset, it will defer to the level of its parent named "abc", and if that level is also unset, the default logger level will be used. -When the level of logger "abc" is changed, all of its descendants (e.g. "abc.def", "abc.ghi.jkl") will have their level impacted unless their level has been explicitly set. - -## Logging usage - -In C++: -- See the [logging demo](Logging-and-logger-configuration) for example usage. -- See the [`rclcpp` documentation](http://docs.ros2.org/latest/api/rclcpp/logging_8hpp.html) for an extensive list of functionality. - -In Python: -- See the [`rclpy` examples](https://github.com/ros2/examples/blob/master/rclpy/services/minimal_client/client.py) for example usage of a node's logger. -- See the [`rclpy` tests](https://github.com/ros2/rclpy/blob/master/rclpy/test/test_logging.py) for example usage of keyword arguments (e.g. `skip_first`, `once`). - -## Logger configuration - -### Command line configuration of the default severity level - -As of the Bouncy ROS 2 release, the default severity level for loggers can be configured from the command line with the following, for example (the level string is not case sensitive): - -``` -ros2 run demo_nodes_cpp listener __log_level:=debug -``` - -This will affect all loggers that have not explicitly been configured to use a particular severity level. -Configuration of specific loggers from the command line is forthcoming. - -### Programmatic configuration of individual loggers - -Logger configuration is still under development. -For now, the severity level of individual loggers can be configured programmatically with, e.g.: - -In C++: -``` -rcutils_logging_set_logger_level("logger_name", RCUTILS_LOG_SEVERITY_DEBUG); -``` - -In Python: -``` -logger.set_level(rclpy.logging.LoggingSeverity.DEBUG) -rclpy.logging.set_logger_level('logger_name', rclpy.logging.LoggingSeverity.DEBUG) -``` - -The [logging demo](Logging-and-logger-configuration) provides an example of manually exposing a service so that loggers can be configured externally; in the future we expect runtime configuration capabilities of loggers to be exposed automatically. - -## Console output configuration - -By default, console output will be formatted to include the message severity, logger name, and the message. -Information such as the file name, function name and line number of the log call are also available. -Custom console output format can be configured with the `RCUTILS_CONSOLE_OUTPUT_FORMAT` environment variable: see the [`rcutils` documentation for details](http://docs.ros2.org/latest/api/rcutils/logging_8h.html#a27340ac73188b1cf8d9cb96d86c76694). -As `rclpy` and `rclcpp` both use `rcutils` for logging, this will effect all Python and C++ nodes. \ No newline at end of file diff --git a/Logging.rst b/Logging.rst new file mode 100644 index 00000000000..46ce3e12186 --- /dev/null +++ b/Logging.rst @@ -0,0 +1,94 @@ + +Logging and logger configuration +================================ + +The logging functionality currently supported is: + + +* Client libraries (\ ``rclcpp`` and ``rclpy``\ ) using a common logging library to provide: + + * Log calls with a variety of filters. + * Hierarchy of loggers. + * Loggers associated with nodes that automatically use the node's name and namespace. + +* Console output. + + * File output and functionality akin to `\ ``rosout`` `__ for remote consumption of messages is forthcoming. + +* Programmatic configuration of logger levels. + + * Launch-time configuration of the default logger level is supported; config files and external configuration at run-time is forthcoming. + +Logger concepts +--------------- + +Log messages have a severity level associated with them: ``DEBUG``\ , ``INFO``\ , ``WARN``\ , ``ERROR`` or ``FATAL``\ , in ascending order. + +A logger will only process log messages with severity at or higher than a specified level chosen for the logger. + +Each node (in ``rclcpp`` and ``rclpy``\ ) has a logger associated with it that automatically includes the node's name and namespace. +If the node's name is externally remapped to something other than what is defined in the source code, it will be reflected in the logger name. +Non-node loggers can also be created that use a specific name. + +Logger names represent a hierarchy. +If the level of a logger named "abc.def" is unset, it will defer to the level of its parent named "abc", and if that level is also unset, the default logger level will be used. +When the level of logger "abc" is changed, all of its descendants (e.g. "abc.def", "abc.ghi.jkl") will have their level impacted unless their level has been explicitly set. + +Logging usage +------------- + +In C++: + + +* See the `logging demo ` for example usage. +* See the `\ ``rclcpp`` documentation `__ for an extensive list of functionality. + +In Python: + + +* See the `\ ``rclpy`` examples `__ for example usage of a node's logger. +* See the `\ ``rclpy`` tests `__ for example usage of keyword arguments (e.g. ``skip_first``\ , ``once``\ ). + +Logger configuration +-------------------- + +Command line configuration of the default severity level +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As of the Bouncy ROS 2 release, the default severity level for loggers can be configured from the command line with the following, for example (the level string is not case sensitive): + +.. code-block:: + + ros2 run demo_nodes_cpp listener __log_level:=debug + +This will affect all loggers that have not explicitly been configured to use a particular severity level. +Configuration of specific loggers from the command line is forthcoming. + +Programmatic configuration of individual loggers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Logger configuration is still under development. +For now, the severity level of individual loggers can be configured programmatically with, e.g.: + +In C++: + +.. code-block:: + + rcutils_logging_set_logger_level("logger_name", RCUTILS_LOG_SEVERITY_DEBUG); + +In Python: + +.. code-block:: + + logger.set_level(rclpy.logging.LoggingSeverity.DEBUG) + rclpy.logging.set_logger_level('logger_name', rclpy.logging.LoggingSeverity.DEBUG) + +The `logging demo ` provides an example of manually exposing a service so that loggers can be configured externally; in the future we expect runtime configuration capabilities of loggers to be exposed automatically. + +Console output configuration +---------------------------- + +By default, console output will be formatted to include the message severity, logger name, and the message. +Information such as the file name, function name and line number of the log call are also available. +Custom console output format can be configured with the ``RCUTILS_CONSOLE_OUTPUT_FORMAT`` environment variable: see the `\ ``rcutils`` documentation for details `__. +As ``rclpy`` and ``rclcpp`` both use ``rcutils`` for logging, this will effect all Python and C++ nodes. diff --git a/MISRA-Compliance-Guide.md b/MISRA-Compliance-Guide.md deleted file mode 100644 index f2046df53bd..00000000000 --- a/MISRA-Compliance-Guide.md +++ /dev/null @@ -1,40 +0,0 @@ -This section tries to give guidance about how to integrate ROS2 into a system that is intended to be compliant with the MISRA (Motor Industry Software Reliability Association) guidelines. - -**What this section is about:** -- ROS2 core packages -- ROS2 core client libraries -- Integration considerations for ROS2 packages in a MISRA-Compliant system - -**What this section is not about:** -- Applying MISRA Guidelines to application and ecosystem ROS2 packages. -- A detailed description of the MISRA Guidelines - -**Relation to other sections of this wiki:** - -- The [Quality Guide](Quality-Guide.md) summarizes overall techniques and strategies for producing high quality ROS2 packages. - -## What are the MISRA guidelines? - -From [MISRA](https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx) -> MISRA was originally established as a collaboration between vehicle manufacturers, component suppliers and engineering consultancies, and seeks to promote best practice in developing safety-related electronic systems in road vehicles and other embedded systems. To this end MISRA publishes documents that provide accessible information for engineers and management, and holds events to permit the exchange of experiences between practitioners. - -MISRA publishes a set of guidelines for both C and C++ that define a subset of the languages that are likely to be free from important programming mistakes for safety-critical systems. The MISRA guidelines are used as a component of [various software standards](https://en.wikipedia.org/wiki/MISRA_C#Adoption), such as: - -* [ISO 26262](https://en.wikipedia.org/wiki/ISO_26262) - "Road Vehicles - Functional Safety" -* [AUTOSAR](https://en.wikipedia.org/wiki/AUTOSAR) - Automotive Open System Architecture - -## Why is this important to ROS2 users? - -As robotics and autonomy grow, especially in the field of self-driving cars, users of ROS will need to be able to determine if the software is able to be used in a safety-critical environment. With suitable guidance and modification, it is expected that ROS2 could be integrated as part of a MISRA compliant system. This would enable users of ROS2 to take their work through multiple stages of the software lifecycle, from prototype through production. - -## Claiming Compliance - -From: [MISRA Compliance:2016](https://www.misra.org.uk/Publications/tabid/57/Default.aspx#label-comp) - -> In order for a claim of MISRA compliance to have meaning, it is necessary to establish: -> * Exactly which guidelines are being applied; -> * The effectiveness of the enforcement methods; -> * The extent to which deviations have been used; -> * Use of a disciplined software development process; -> * The status of any components developed outside of the project. - diff --git a/MISRA-Compliance-Guide.rst b/MISRA-Compliance-Guide.rst new file mode 100644 index 00000000000..70268b3f017 --- /dev/null +++ b/MISRA-Compliance-Guide.rst @@ -0,0 +1,58 @@ + +This section tries to give guidance about how to integrate ROS2 into a system that is intended to be compliant with the MISRA (Motor Industry Software Reliability Association) guidelines. + +**What this section is about:** + + +* ROS2 core packages +* ROS2 core client libraries +* Integration considerations for ROS2 packages in a MISRA-Compliant system + +**What this section is not about:** + + +* Applying MISRA Guidelines to application and ecosystem ROS2 packages. +* A detailed description of the MISRA Guidelines + +**Relation to other sections of this wiki:** + + +* The `Quality Guide ` summarizes overall techniques and strategies for producing high quality ROS2 packages. + +What are the MISRA guidelines? +------------------------------ + +From `MISRA `__ + +.. + + MISRA was originally established as a collaboration between vehicle manufacturers, component suppliers and engineering consultancies, and seeks to promote best practice in developing safety-related electronic systems in road vehicles and other embedded systems. To this end MISRA publishes documents that provide accessible information for engineers and management, and holds events to permit the exchange of experiences between practitioners. + + +MISRA publishes a set of guidelines for both C and C++ that define a subset of the languages that are likely to be free from important programming mistakes for safety-critical systems. The MISRA guidelines are used as a component of `various software standards `__\ , such as: + + +* `ISO 26262 `__ - "Road Vehicles - Functional Safety" +* `AUTOSAR `__ - Automotive Open System Architecture + +Why is this important to ROS2 users? +------------------------------------ + +As robotics and autonomy grow, especially in the field of self-driving cars, users of ROS will need to be able to determine if the software is able to be used in a safety-critical environment. With suitable guidance and modification, it is expected that ROS2 could be integrated as part of a MISRA compliant system. This would enable users of ROS2 to take their work through multiple stages of the software lifecycle, from prototype through production. + +Claiming Compliance +------------------- + +From: `MISRA Compliance:2016 `__ + +.. + + In order for a claim of MISRA compliance to have meaning, it is necessary to establish: + + + * Exactly which guidelines are being applied; + * The effectiveness of the enforcement methods; + * The extent to which deviations have been used; + * Use of a disciplined software development process; + * The status of any components developed outside of the project. + diff --git a/Maintaining-a-Source-Checkout.md b/Maintaining-a-Source-Checkout.md deleted file mode 100644 index 70846ec8910..00000000000 --- a/Maintaining-a-Source-Checkout.md +++ /dev/null @@ -1,127 +0,0 @@ -# Maintaining a Source Checkout of ROS 2 -If you have installed ROS 2 from source, there may have been changes made to the source code since the time that you checked it out. -To keep your source checkout up to date, you will have to periodically update your `ros2.repos` file, download the latest sources, and rebuild your workspace. - -## Update your repository list -Each ROS 2 release includes a `ros2.repos` file that contains the list of repositories and their version for that release. - -### Latest release -To download the repository list from the latest ROS 2 release, run: - -#### _Linux/OS X_ -``` -cd ~/ros2_ws -mv -i ros2.repos ros2.repos.old -wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -``` - -#### _Windows_ -``` -# CMD -> cd \dev\ros2 -> curl -sk https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos - -# PowerShell -> cd \dev\ros2 -> curl https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos -``` - -### Particular release -If you wish to checkout a particular release, you can get its repository list by specifying the name of the release in the url of the following step, e.g. for alpha 7: - -#### _Linux/OS X_ -``` -cd ~/ros2_ws -mv -i ros2.repos ros2.repos.old -wget https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos -``` - -#### _Windows_ -``` -# CMD -> cd \dev\ros2 -> curl -sk https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos -o ros2.repos - -# PowerShell -> cd \dev\ros2 -> curl https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos -o ros2.repos -``` - -The format of the name of the release comes from the tag associated with the release [here](https://github.com/ros2/ros2/tags). - -### Development branches -If you wish to checkout the bleeding-edge development code, you can get the relevant repository list by running: - -#### _Linux/OS X_ -``` -cd ~/ros2_ws -mv -i ros2.repos ros2.repos.old -wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -``` - -#### _Windows_ -``` -# CMD -> cd \dev\ros2 -> curl -sk https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -o ros2.repos - -# PowerShell -> cd \dev\ros2 -> curl https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -o ros2.repos -``` - - -## Update your repositories -You will notice that in the [`ros2.repos` file](https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos), each repository has a `version` associated with it that points to a particular commit hash, tag, or branch name. -It is possible that these versions refer to new tags/branches that your local copy of the repositories will not recognize as they are out-of-date. -Because of this, you should update the repositories that you have already checked out with the following command: - -``` -vcs custom --args remote update -``` - - -## Download the new source code -You should now be able to download the sources associated with the new repository list with: - -#### _Linux/OS X_ -``` -vcs import src < ros2.repos -vcs pull src -``` - -#### _Windows_ -``` -# CMD -> vcs import src < ros2.repos -> vcs pull src - -# PowerShell -> vcs import --input ros2.repos src -> vcs pull src -``` - -## Rebuild your workspace -Now that the workspace is up to date with the latest sources, remove your previous install and rebuild your workspace with, for example: - -``` -colcon build --symlink-install -``` - -## Inspecting your source checkout -During your development you may have deviated from the original state of your workspace from when you imported the repository list. -If you wish to know the versions of the set of repositories in your workspace, you can export the information using the following command: - -#### _Linux/OS X_ -``` -cd ~/ros2_ws -vcs export src > my_ros2.repos -``` - -#### _Windows_ -``` -> cd \dev\ros2 -> vcs export src > my_ros2.repos -``` - -This `my_ros2.repos` file can then be shared with others so that they can reproduce the state of the repositories in your workspace. diff --git a/Maintaining-a-Source-Checkout.rst b/Maintaining-a-Source-Checkout.rst new file mode 100644 index 00000000000..a8ed5343a61 --- /dev/null +++ b/Maintaining-a-Source-Checkout.rst @@ -0,0 +1,164 @@ + +Maintaining a Source Checkout of ROS 2 +====================================== + +If you have installed ROS 2 from source, there may have been changes made to the source code since the time that you checked it out. +To keep your source checkout up to date, you will have to periodically update your ``ros2.repos`` file, download the latest sources, and rebuild your workspace. + +Update your repository list +--------------------------- + +Each ROS 2 release includes a ``ros2.repos`` file that contains the list of repositories and their version for that release. + +Latest release +^^^^^^^^^^^^^^ + +To download the repository list from the latest ROS 2 release, run: + +*Linux/OS X* +~~~~~~~~~~~~~~~~ + +.. code-block:: + + cd ~/ros2_ws + mv -i ros2.repos ros2.repos.old + wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos + +*Windows* +~~~~~~~~~~~~~ + +.. code-block:: + + # CMD + > cd \dev\ros2 + > curl -sk https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos + + # PowerShell + > cd \dev\ros2 + > curl https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos + +Particular release +^^^^^^^^^^^^^^^^^^ + +If you wish to checkout a particular release, you can get its repository list by specifying the name of the release in the url of the following step, e.g. for alpha 7: + +*Linux/OS X* +~~~~~~~~~~~~~~~~ + +.. code-block:: + + cd ~/ros2_ws + mv -i ros2.repos ros2.repos.old + wget https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos + +*Windows* +~~~~~~~~~~~~~ + +.. code-block:: + + # CMD + > cd \dev\ros2 + > curl -sk https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos -o ros2.repos + + # PowerShell + > cd \dev\ros2 + > curl https://raw.githubusercontent.com/ros2/ros2/release-alpha8/ros2.repos -o ros2.repos + +The format of the name of the release comes from the tag associated with the release `here `__. + +Development branches +^^^^^^^^^^^^^^^^^^^^ + +If you wish to checkout the bleeding-edge development code, you can get the relevant repository list by running: + +*Linux/OS X* +~~~~~~~~~~~~~~~~ + +.. code-block:: + + cd ~/ros2_ws + mv -i ros2.repos ros2.repos.old + wget https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos + +*Windows* +~~~~~~~~~~~~~ + +.. code-block:: + + # CMD + > cd \dev\ros2 + > curl -sk https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -o ros2.repos + + # PowerShell + > cd \dev\ros2 + > curl https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos -o ros2.repos + +Update your repositories +------------------------ + +You will notice that in the `ros2.repos `__ file, each repository has a ``version`` associated with it that points to a particular commit hash, tag, or branch name. +It is possible that these versions refer to new tags/branches that your local copy of the repositories will not recognize as they are out-of-date. +Because of this, you should update the repositories that you have already checked out with the following command: + +.. code-block:: + + vcs custom --args remote update + +Download the new source code +---------------------------- + +You should now be able to download the sources associated with the new repository list with: + +*Linux/OS X* +~~~~~~~~~~~~~~~~ + +.. code-block:: + + vcs import src < ros2.repos + vcs pull src + +*Windows* +~~~~~~~~~~~~~ + +.. code-block:: + + # CMD + > vcs import src < ros2.repos + > vcs pull src + + # PowerShell + > vcs import --input ros2.repos src + > vcs pull src + +Rebuild your workspace +---------------------- + +Now that the workspace is up to date with the latest sources, remove your previous install and rebuild your workspace with, for example: + +.. code-block:: + + colcon build --symlink-install + +Inspecting your source checkout +------------------------------- + +During your development you may have deviated from the original state of your workspace from when you imported the repository list. +If you wish to know the versions of the set of repositories in your workspace, you can export the information using the following command: + +*Linux/OS X* +~~~~~~~~~~~~~~~~ + +.. code-block:: + + cd ~/ros2_ws + vcs export src > my_ros2.repos + +*Windows* +~~~~~~~~~~~~~ + +.. code-block:: + + > cd \dev\ros2 + > vcs export src > my_ros2.repos + +This ``my_ros2.repos`` file can then be shared with others so that they can reproduce the state of the repositories in your workspace. diff --git a/Managed-Nodes.md b/Managed-Nodes.md deleted file mode 100644 index 8895d867ae6..00000000000 --- a/Managed-Nodes.md +++ /dev/null @@ -1,181 +0,0 @@ -## Introduction -ROS2 introduces the concept of managed nodes, also called `LifecycleNode`s. In the following tutorial, we explain the purpose of these nodes, what makes them different from regular nodes and how they comply to a lifecycle management. -Managed nodes are scoped within a state machine of a finite amount of states. These states can be changed by invoking a transition id which indicates the succeeding consecutive state. -The state machine is implemented as described at the [ROS2 design page](http://design.ros2.org/articles/node_lifecycle.html). - -Our implementation differentiates between `Primary States` and `Transition States`. Primary States are supposed to be steady states in which any node can do the respected task. On the other hand, Transition States are meant as temporary intermediate states attached to a transition. The result of these intermediate states are used to indicate whether a transition between two primary states is considered successful or not. Thus, any managed node can be in one of the following states: - -Primary States (steady states): -* unconfigured -* inactive -* active -* shutdown - -Transition States (intermediate states): -* configuring -* activating -* deactivating -* cleaningup -* shuttingdown - -The possible transitions to invoke are: -* configure -* activate -* deactivate -* cleanup -* shutdown - -For a more verbose explanation on the applied state machine, we refer to the design page which provides an in-detail explanation about each state and transition. - -## The demo -### What's happening -The demo is split into 3 different separate applications. -* lifecycle_talker -* lifecycle_listener -* lifecycle_service_client - -The `lifecycle_talker` represents a managed node and publishes according to which state the node is in. We split the tasks of the talker node into separate pieces and execute them as followed. - 1. configuring: We initialize our publisher and timer - 2. activate: We activate the publisher and timer in order to enable a publishing - 3. deactivate: We stop the publisher and timer - 4. cleanup: We destroy the publisher and timer - -The principle is implemented in this demo as the typical talker/listener demo. However, imaging a real scenario with attached hardware which may have a rather long booting phase, i.e. a laser or camera. One could image bringing up the device driver in the configuring state, start and stop only the publishing of the device's data and only in the cleanup/shutdown phase actually shutdown the device. - -The `lifecycle_listener` is a simple listener which shows the characteristics of the lifecycle talker. The talker enables the message publishing only in the active state and thus making the listener receiving only messages when the talker is in an active state. - -The `lifecycle_service_client` is a script calling different transitions on the `lifecycle_talker`. This is meant as the external user controlling the lifecycle of nodes. - -## Run the demo -In order to run this demo, we open three terminals and source our ROS2 environment variables either from the binary distributions or the workspace we compiled from source. - -|lifecycle_talker|lifecycle_listener|lifecycle_service_client| -|----------------|------------------|------------------------| -|```$ ros2 run lifecycle lifecycle_talker```| ```$ ros2 run lifecycle lifecycle_listener```|```$ ros2 run lifecycle lifecycle_service_client```| -|[![asciicast](https://asciinema.org/a/e0f11qvpberltp8r1w04wzw9t.png)](https://asciinema.org/a/e0f11qvpberltp8r1w04wzw9t)|[![asciicast](https://asciinema.org/a/442pjcu729t3vsld7n225orl7.png)](https://asciinema.org/a/442pjcu729t3vsld7n225orl7)|[![asciicast](https://asciinema.org/a/6o20wbnhx6tk3y2hr5dk8fwm5.png)](https://asciinema.org/a/6o20wbnhx6tk3y2hr5dk8fwm5)| - - -Alternatively, these three programs can be run together in the same terminal using the launch file (as of ROS 2 Bouncy): - -``` -ros2 launch lifecycle lifecycle_demo.launch.py -``` - - -If we look at the output of the `lifecycle_talker`, we notice that nothing seems to happen. And this does make sense, since every node starts as `unconfigured`. The lifecycle_talker is not configured yet and in our example, no publishers and timers are created yet. -The same behavior can be seen for the `lifecycle_listener`, which is less surprising given that no publishers are available at this moment. -The interesting part starts with the third terminal. In there we launch our `lifecycle_service_client` which is responsible for changing the states of the `lifecycle_talker`. - -#### Triggering transition 1 (configure) -``` -[lc_client] Transition 1 successfully triggered. -[lc_client] Node lc_talker has current state inactive. -``` -makes the lifecycle talker change its state to inactive. Inactive means that all publishers and timers are created and configured. However, the node is still not active. Therefore no messages are getting published. -``` -[lc_talker] on_configure() is called. -Lifecycle publisher is currently inactive. Messages are not published. -... -``` -The lifecycle listener on the same time receives a notification as it listens to every state change notification of the lifecycle talker. In fact, the listener receives two consecutive notifications. One for changing from the primary state "unconfigured" to "configuring". Because the configuring step was successful within the lifecycle talker, a second notification from "configuring" to "inactive". -``` -[lc_listener] notify callback: Transition from state unconfigured to configuring -[lc_listener] notify callback: Transition from state configuring to inactive -``` - -#### Triggering transition 2 (activate) -``` -[lc_client] Transition 2 successfully triggered. -[lc_client] Node lc_talker has current state active. -``` -makes the lifecycle talker change its state to active. Active means that all publishers and timers are now activated. Therefore the messages are now getting published. -``` -[lc_talker] on_activate() is called. -[lc_talker] Lifecycle publisher is active. Publishing: [Lifecycle HelloWorld #11] -[lc_talker] Lifecycle publisher is active. Publishing: [Lifecycle HelloWorld #12] -... -``` -The lifecycle listener receives the same set of notifications as before. Lifecycle talker changed its state from inactive to active. -``` -[lc_listener] notify callback: Transition from state unconfigured to configuring -[lc_listener] notify callback: Transition from state configuring to inactive -``` -The difference to the transition event before is that our listener now also receives the actual published data. -``` -[lc_listener] data_callback: Lifecycle HelloWorld #11 -[lc_listener] data_callback: Lifecycle HelloWorld #12 -... -``` -Please note that the index of the published message is already at 11. The purpose of this demo is to show that even though we call `publish` at every state of the lifecycle talker, only when the state in active, the messages are actually published. As for the beta1, all other messages are getting ignored. This behavior may change in future versions in order to provide better error handling. - -For the rest of the demo, you will see similar output as we deactivate and activate the lifecycle talker and finally shut it down. - -## The demo code - -#### lifecycle_talker, lifecycle_listener and lifecycle_service_client -If we have a look at the code, there is one significant change for the lifecycle talker compared to a regular talker. Our node does not inherit from the regular ```rclcpp::node::Node``` but from ```rclcpp_lifecycle::LifecycleNode```. -``` -class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode -``` -Every child of LifecycleNodes have a set of callbacks provided. These callbacks go along with the applied state machine attached to it. These callbacks are: -* ```rcl_lifecycle_ret_t on_configure(const rclcpp_lifecycle::State & previous_state)``` -* ```rcl_lifecycle_ret_t on_activate(const rclcpp_lifecycle::State & previous_state)``` -* ```rcl_lifecycle_ret_t on_deactivate(const rclcpp_lifecycle::State & previous_state)``` -* ```rcl_lifecycle_ret_t on_cleanup(const rclcpp_lifecycle::State & previous_state)``` -* ```rcl_lifecycle_ret_t on_shutdown(const rclcpp_lifecycle::State & previous_state)``` - -All these callbacks have a positive default return value (```return RCL_LIFECYCLE_RET_OK```). This allows a lifecycle node to change its state even though no explicit callback function was overwritten. -There is one other callback function for error handling. Whenever a state transition throws an uncaught exception, we call ```on_error```. -* ```rcl_lifecycle_ret_t on_error(const rclcpp_lifecycle::State & previous_state)``` - -This gives room for executing a custom error handling. Only (!) in the case that this function returns ```RCL_LIFECYCLE_RET_OK```, the state machine transitions to the state `unconfigured`. By default, the `on_error` returns `RCL_LIFECYCLE_RET_ERROR` and the state machine transitions into `finalized`. - -At the same time, every lifecycle node has by default 5 different communication interfaces. -* Publisher `__transition_event`: publishes in case a transition is happening. This allows users to get notified of transition events within the network. -* Service `__get_state`: query about the current state of the node. Return either a primary or transition state. -* Service `__change_state`: triggers a transition for the current node. This service call takes a transition id. Only in the case, that this transition ID is a valid transition of the current state, the transition is fulfilled. All other cases are getting ignored. -* Service `__get_available_states`: This is meant to be an introspection tool. It returns a list of all possible states this node can be. -* Service `__get_available_transitions`: Same as above, meant to an introspection tool. It returns a list of all possible transitions this node can execute. - -### lifecycle_service_client_py.py -The `lifecycle_service_client` application is a fixed order script for this demo purpose only. It explains the use and the API calls made for this lifecycle implementation, but may be inconvenient to use otherwise. For this reason, we implemented a separate python script, which lets you dynamically change states or various nodes. -``` -$ ros2 run lifecycle lifecycle_service_client_py.py -usage: lifecycle_service_client_py.py [-h] - [--change-state-args {configure,cleanup,shutdown,activate,deactivate}] - {change_state,get_state,get_available_states,get_available_transitions} - node -``` -In the case you want to get the current state of the `lc_talker` node, you'd call: -``` -$ ros2 run lifecycle lifecycle_service_client_py.py get_state lc_talker -lc_talker is in state unconfigured(1) -``` -The next step would be to execute a state change: -``` -$ ros2 run lifecycle lifecycle_service_client_py.py change_state --change-state-args configure lc_talker -``` - -All of the above commands are nothing else than calling the lifecycle node's services. With that being said, we can also call these services directly with the ros2 command line interface: -``` -$ ros2 service call /lc_talker/get_state lifecycle_msgs/GetState "{node_name: lc_talker}" -requester: making request: lifecycle_msgs.srv.GetState_Request(node_name='lc_talker') - -response: -lifecycle_msgs.srv.GetState_Response(current_state=lifecycle_msgs.msg.State(id=1, label='unconfigured')) -``` -In order to trigger a transition, we call the `change_state` service -``` -$ ros2 service call /lc_talker/change_state lifecycle_msgs/ChangeState "{node_name: lc_talker, transition: {id: 2}}" -requester: making request: lifecycle_msgs.srv.ChangeState_Request(node_name='lc_talker', transition=lifecycle_msgs.msg.Transition(id=2, label='')) - -response: -lifecycle_msgs.srv.ChangeState_Response(success=True) -``` -It is slightly less convenient, because you have to know the IDs which correspond to each transition. You can find them though in the lifecycle_msgs package. - -## Outlook -The above description points to the current state of the development as for beta1. The future todo list for this topic comprises: -* Python lifecycle nodes -* Lifecycle manager: A global node, handling and dispatching trigger requests for multiple nodes. -* LifeyclceSubscriber/LifecycleWalltimer/... add more lifecycle controlled entities. diff --git a/Managed-Nodes.rst b/Managed-Nodes.rst new file mode 100644 index 00000000000..005bec670a8 --- /dev/null +++ b/Managed-Nodes.rst @@ -0,0 +1,260 @@ + +Introduction +------------ + +ROS2 introduces the concept of managed nodes, also called ``LifecycleNode``\ s. In the following tutorial, we explain the purpose of these nodes, what makes them different from regular nodes and how they comply to a lifecycle management. +Managed nodes are scoped within a state machine of a finite amount of states. These states can be changed by invoking a transition id which indicates the succeeding consecutive state. +The state machine is implemented as described at the `ROS2 design page `__. + +Our implementation differentiates between ``Primary States`` and ``Transition States``. Primary States are supposed to be steady states in which any node can do the respected task. On the other hand, Transition States are meant as temporary intermediate states attached to a transition. The result of these intermediate states are used to indicate whether a transition between two primary states is considered successful or not. Thus, any managed node can be in one of the following states: + +Primary States (steady states): + + +* unconfigured +* inactive +* active +* shutdown + +Transition States (intermediate states): + + +* configuring +* activating +* deactivating +* cleaningup +* shuttingdown + +The possible transitions to invoke are: + + +* configure +* activate +* deactivate +* cleanup +* shutdown + +For a more verbose explanation on the applied state machine, we refer to the design page which provides an in-detail explanation about each state and transition. + +The demo +-------- + +What's happening +^^^^^^^^^^^^^^^^ + +The demo is split into 3 different separate applications. + + +* lifecycle_talker +* lifecycle_listener +* lifecycle_service_client + +The ``lifecycle_talker`` represents a managed node and publishes according to which state the node is in. We split the tasks of the talker node into separate pieces and execute them as followed. + + +#. configuring: We initialize our publisher and timer +#. activate: We activate the publisher and timer in order to enable a publishing +#. deactivate: We stop the publisher and timer +#. cleanup: We destroy the publisher and timer + +The principle is implemented in this demo as the typical talker/listener demo. However, imaging a real scenario with attached hardware which may have a rather long booting phase, i.e. a laser or camera. One could image bringing up the device driver in the configuring state, start and stop only the publishing of the device's data and only in the cleanup/shutdown phase actually shutdown the device. + +The ``lifecycle_listener`` is a simple listener which shows the characteristics of the lifecycle talker. The talker enables the message publishing only in the active state and thus making the listener receiving only messages when the talker is in an active state. + +The ``lifecycle_service_client`` is a script calling different transitions on the ``lifecycle_talker``. This is meant as the external user controlling the lifecycle of nodes. + +Run the demo +------------ + +In order to run this demo, we open three terminals and source our ROS2 environment variables either from the binary distributions or the workspace we compiled from source. + +.. list-table:: + :header-rows: 1 + + * - lifecycle_talker + - lifecycle_listener + - lifecycle_service_client + * - ``$ ros2 run lifecycle lifecycle_talker`` + - ``$ ros2 run lifecycle lifecycle_listener`` + - ``$ ros2 run lifecycle lifecycle_service_client`` + * - + .. image:: https://asciinema.org/a/e0f11qvpberltp8r1w04wzw9t.png + :target: https://asciinema.org/a/e0f11qvpberltp8r1w04wzw9t + :alt: asciicast + + - + .. image:: https://asciinema.org/a/442pjcu729t3vsld7n225orl7.png + :target: https://asciinema.org/a/442pjcu729t3vsld7n225orl7 + :alt: asciicast + + - + .. image:: https://asciinema.org/a/6o20wbnhx6tk3y2hr5dk8fwm5.png + :target: https://asciinema.org/a/6o20wbnhx6tk3y2hr5dk8fwm5 + :alt: asciicast + + + +Alternatively, these three programs can be run together in the same terminal using the launch file (as of ROS 2 Bouncy): + +.. code-block:: + + ros2 launch lifecycle lifecycle_demo.launch.py + +If we look at the output of the ``lifecycle_talker``\ , we notice that nothing seems to happen. And this does make sense, since every node starts as ``unconfigured``. The lifecycle_talker is not configured yet and in our example, no publishers and timers are created yet. +The same behavior can be seen for the ``lifecycle_listener``\ , which is less surprising given that no publishers are available at this moment. +The interesting part starts with the third terminal. In there we launch our ``lifecycle_service_client`` which is responsible for changing the states of the ``lifecycle_talker``. + +Triggering transition 1 (configure) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: + + [lc_client] Transition 1 successfully triggered. + [lc_client] Node lc_talker has current state inactive. + +makes the lifecycle talker change its state to inactive. Inactive means that all publishers and timers are created and configured. However, the node is still not active. Therefore no messages are getting published. + +.. code-block:: + + [lc_talker] on_configure() is called. + Lifecycle publisher is currently inactive. Messages are not published. + ... + +The lifecycle listener on the same time receives a notification as it listens to every state change notification of the lifecycle talker. In fact, the listener receives two consecutive notifications. One for changing from the primary state "unconfigured" to "configuring". Because the configuring step was successful within the lifecycle talker, a second notification from "configuring" to "inactive". + +.. code-block:: + + [lc_listener] notify callback: Transition from state unconfigured to configuring + [lc_listener] notify callback: Transition from state configuring to inactive + +Triggering transition 2 (activate) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: + + [lc_client] Transition 2 successfully triggered. + [lc_client] Node lc_talker has current state active. + +makes the lifecycle talker change its state to active. Active means that all publishers and timers are now activated. Therefore the messages are now getting published. + +.. code-block:: + + [lc_talker] on_activate() is called. + [lc_talker] Lifecycle publisher is active. Publishing: [Lifecycle HelloWorld #11] + [lc_talker] Lifecycle publisher is active. Publishing: [Lifecycle HelloWorld #12] + ... + +The lifecycle listener receives the same set of notifications as before. Lifecycle talker changed its state from inactive to active. + +.. code-block:: + + [lc_listener] notify callback: Transition from state unconfigured to configuring + [lc_listener] notify callback: Transition from state configuring to inactive + +The difference to the transition event before is that our listener now also receives the actual published data. + +.. code-block:: + + [lc_listener] data_callback: Lifecycle HelloWorld #11 + [lc_listener] data_callback: Lifecycle HelloWorld #12 + ... + +Please note that the index of the published message is already at 11. The purpose of this demo is to show that even though we call ``publish`` at every state of the lifecycle talker, only when the state in active, the messages are actually published. As for the beta1, all other messages are getting ignored. This behavior may change in future versions in order to provide better error handling. + +For the rest of the demo, you will see similar output as we deactivate and activate the lifecycle talker and finally shut it down. + +The demo code +------------- + +lifecycle_talker, lifecycle_listener and lifecycle_service_client +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we have a look at the code, there is one significant change for the lifecycle talker compared to a regular talker. Our node does not inherit from the regular ``rclcpp::node::Node`` but from ``rclcpp_lifecycle::LifecycleNode``. + +.. code-block:: + + class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode + +Every child of LifecycleNodes have a set of callbacks provided. These callbacks go along with the applied state machine attached to it. These callbacks are: + + +* ``rcl_lifecycle_ret_t on_configure(const rclcpp_lifecycle::State & previous_state)`` +* ``rcl_lifecycle_ret_t on_activate(const rclcpp_lifecycle::State & previous_state)`` +* ``rcl_lifecycle_ret_t on_deactivate(const rclcpp_lifecycle::State & previous_state)`` +* ``rcl_lifecycle_ret_t on_cleanup(const rclcpp_lifecycle::State & previous_state)`` +* ``rcl_lifecycle_ret_t on_shutdown(const rclcpp_lifecycle::State & previous_state)`` + +All these callbacks have a positive default return value (\ ``return RCL_LIFECYCLE_RET_OK``\ ). This allows a lifecycle node to change its state even though no explicit callback function was overwritten. +There is one other callback function for error handling. Whenever a state transition throws an uncaught exception, we call ``on_error``. + + +* ``rcl_lifecycle_ret_t on_error(const rclcpp_lifecycle::State & previous_state)`` + +This gives room for executing a custom error handling. Only (!) in the case that this function returns ``RCL_LIFECYCLE_RET_OK``\ , the state machine transitions to the state ``unconfigured``. By default, the ``on_error`` returns ``RCL_LIFECYCLE_RET_ERROR`` and the state machine transitions into ``finalized``. + +At the same time, every lifecycle node has by default 5 different communication interfaces. + + +* Publisher ``__transition_event``\ : publishes in case a transition is happening. This allows users to get notified of transition events within the network. +* Service ``__get_state``\ : query about the current state of the node. Return either a primary or transition state. +* Service ``__change_state``\ : triggers a transition for the current node. This service call takes a transition id. Only in the case, that this transition ID is a valid transition of the current state, the transition is fulfilled. All other cases are getting ignored. +* Service ``__get_available_states``\ : This is meant to be an introspection tool. It returns a list of all possible states this node can be. +* Service ``__get_available_transitions``\ : Same as above, meant to an introspection tool. It returns a list of all possible transitions this node can execute. + +lifecycle_service_client_py.py +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``lifecycle_service_client`` application is a fixed order script for this demo purpose only. It explains the use and the API calls made for this lifecycle implementation, but may be inconvenient to use otherwise. For this reason, we implemented a separate python script, which lets you dynamically change states or various nodes. + +.. code-block:: + + $ ros2 run lifecycle lifecycle_service_client_py.py + usage: lifecycle_service_client_py.py [-h] + [--change-state-args {configure,cleanup,shutdown,activate,deactivate}] + {change_state,get_state,get_available_states,get_available_transitions} + node + +In the case you want to get the current state of the ``lc_talker`` node, you'd call: + +.. code-block:: + + $ ros2 run lifecycle lifecycle_service_client_py.py get_state lc_talker + lc_talker is in state unconfigured(1) + +The next step would be to execute a state change: + +.. code-block:: + + $ ros2 run lifecycle lifecycle_service_client_py.py change_state --change-state-args configure lc_talker + +All of the above commands are nothing else than calling the lifecycle node's services. With that being said, we can also call these services directly with the ros2 command line interface: + +.. code-block:: + + $ ros2 service call /lc_talker/get_state lifecycle_msgs/GetState "{node_name: lc_talker}" + requester: making request: lifecycle_msgs.srv.GetState_Request(node_name='lc_talker') + + response: + lifecycle_msgs.srv.GetState_Response(current_state=lifecycle_msgs.msg.State(id=1, label='unconfigured')) + +In order to trigger a transition, we call the ``change_state`` service + +.. code-block:: + + $ ros2 service call /lc_talker/change_state lifecycle_msgs/ChangeState "{node_name: lc_talker, transition: {id: 2}}" + requester: making request: lifecycle_msgs.srv.ChangeState_Request(node_name='lc_talker', transition=lifecycle_msgs.msg.Transition(id=2, label='')) + + response: + lifecycle_msgs.srv.ChangeState_Response(success=True) + +It is slightly less convenient, because you have to know the IDs which correspond to each transition. You can find them though in the lifecycle_msgs package. + +Outlook +------- + +The above description points to the current state of the development as for beta1. The future todo list for this topic comprises: + + +* Python lifecycle nodes +* Lifecycle manager: A global node, handling and dispatching trigger requests for multiple nodes. +* LifeyclceSubscriber/LifecycleWalltimer/... add more lifecycle controlled entities. diff --git a/Migration-Guide.md b/Migration-Guide.md deleted file mode 100644 index 8ad7c4dfa0d..00000000000 --- a/Migration-Guide.md +++ /dev/null @@ -1,822 +0,0 @@ -# Migration guide from ROS 1 - -This article describes the high-level steps to migrate a ROS 1 package to ROS 2. -It does not aim to be a step-by-step migration instruction and is not considered the *final* "solution". -Future versions will aim to make migration smoother and less effort up to the point that maintaining a single package from the same branch for ROS 1 as well as ROS 2 - -Migration Steps: - -* [Package Manifests](#Package-manifests) -* [Message and service definitions](#Message-and-service-definitions) -* [Source Code](#Update-source-code) -* [Build System](#Build-system) -* [Launch Files](#Launch-files) -* [Licensing](#licensing) - -## Prerequisite - -Before being able to migrate a ROS 1 package to ROS 2 all of its dependencies must be available in ROS 2. - -## Migration steps - -### Package manifests - -ROS 2 only support the format 2 of the package specification which is defined in [REP 140](http://www.ros.org/reps/rep-0140.html). -Therefore the `package.xml` file must be updated to format 2 if it uses format 1. -Since ROS 1 support both formats (1 as well as 2) it is safe to perform that conversion in the ROS 1 package. - -Some packages might have different names in ROS 2 so the dependencies might need to be updated accordingly. - -### Message and service definitions - -Message files must end in `.msg` and must be located in the subfolder `msg`. -Service files must end in `.srv` and must be located in the subfolder `srv`. - -These files might need to be updated to comply with the [ROS Interface definition](http://design.ros2.org/articles/interface_definition.html). -Some primitive types have been removed and the types `duration` and `time` which were builtin types in ROS 1 have been replaced with normal message definitions and must be used from the [`builtin_interfaces`](https://github.com/ros2/rcl_interfaces/tree/master/builtin_interfaces) package. -Also some naming conventions are stricter then in ROS 1. - -In your `package.xml` you will need to add: - -- `rosidl_default_generators` -- `rosidl_default_runtime` -- For each dependent message package add `message_package` - -In your `CMakeLists.txt`: - -Start by enabling C++11 - -``` cmake -if(NOT WIN32) - add_definitions(-std=c++11) -endif() -``` - -- `find_package(rosidl_default_generators REQUIRED)` -- For each dependent message package add `find_package(message_package REQUIRED)` and replace the cmake function call to `generate_messages` with `rosidl_generate_interfaces` - -This will replace `add_message_files` and `add_service_files` listing of all the message and service files, which can be removed. - -### Build system - -The build system in ROS 2 is called [ament](http://design.ros2.org/articles/ament.html). - -#### Build tool - -Instead of using `catkin_make`, `catkin_make_isolated` or `catkin build` ROS 2 uses the command line tool [colcon](http://design.ros2.org/articles/build_tool.html) to build and install a set of packages. - -#### Pure Python package - -If the ROS 1 package uses CMake only to invoke the `setup.py` file and does not contain anything beside Python code (e.g. also no messages, services, etc.) it should be converted into a pure Python package in ROS 2: - -- Update or add the build type in the `package.xml` file: - - ``` xml - - ament_python - - ``` - -- Remove the `CMakeLists.txt` file - -- Update the `setup.py` file to be a standard Python setup script - -ROS 2 supports Python 3 only. -While each package can choose to also support Python 2 it must invoke executables with Python 3 if it uses any API provided by other ROS 2 packages. - -#### Update the *CMakeLists.txt* to use *ament_cmake* - -Apply the following changes to use `ament_cmake` instead of `catkin`: - -- Set the build type in the `package.xml` file export section: - - ``` xml - - ament_cmake - - ``` - -- Replace the `find_package` invocation with `catkin` and the `COMPONENTS` with: - - ``` cmake - find_package(ament_cmake REQUIRED) - find_package(component1 REQUIRED) - # ... - find_package(componentN REQUIRED) - ``` - -- Move and update the `catkin_package` invocation with: - - - Invoke `ament_package` instead but **after** all targets have been registered. - - - The only valid argument for [ament_package](https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/cmake/core/ament_package.cmake) is `CONFIG_EXTRAS`. - All other arguments are covered by separate functions which all need to be invoked *before* `ament_package`. - - - **TODO document ament_export_interfaces?** - -- Replace the invocation of `add_message_files`, `add_service_files` and `generate_messages` with [rosidl_generate_interfaces](https://github.com/ros2/rosidl/blob/master/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake). - - - The first argument is the `target_name`. - If you're building just one library it's `${PROJECT_NAME}` - - - Followed by the list of message filenames, relative to the package root. - - - If you will be using the list of filenames multiple times, it is recommended to compose a list of message files and pass the list to the function for clarity. - - - The final multi-value-keyword argument fpr `generate_messages` is `DEPENDENCIES` which requires the list of dependent message packages. - - ``` cmake - rosidl_generate_interfaces(${PROJECT_NAME} - ${msg_files} - DEPENDENCIES std_msgs - ) - ``` - -- Remove any occurrences of the *devel space*. - Related CMake variables like `CATKIN_DEVEL_PREFIX` do not exist anymore. - - - The `CATKIN_DEPENDS` and `DEPENDS` arguments are passed to the new function [ament_export_dependencies](https://github.com/ament/ament_cmake/blob/master/ament_cmake_export_dependencies/cmake/ament_export_dependencies.cmake). - -- Replace the invocation of `add_message_files`, `add_service_files` and `generate_messages` with [rosidl_generate_interfaces](https://github.com/ros2/rosidl/blob/master/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake). - -- Remove any occurrences of the *devel space*. - Related CMake variables like `CATKIN_DEVEL_PREFIX` do not exist anymore. - - - `CATKIN_GLOBAL_BIN_DESTINATION`: `bin` - - `CATKIN_GLOBAL_INCLUDE_DESTINATION`: `include` - - `CATKIN_GLOBAL_LIB_DESTINATION`: `lib` - - `CATKIN_GLOBAL_LIBEXEC_DESTINATION`: `lib` - - `CATKIN_GLOBAL_SHARE_DESTINATION`: `share` - - `CATKIN_PACKAGE_BIN_DESTINATION`: `lib/${PROJECT_NAME}` - - `CATKIN_PACKAGE_INCLUDE_DESTINATION`: `include/${PROJECT_NAME}` - - `CATKIN_PACKAGE_LIB_DESTINATION`: `lib` - - `CATKIN_PACKAGE_SHARE_DESTINATION`: `share/${PROJECT_NAME}` - -#### Unit tests - -If you are using gtest - -- replace `CATKIN_ENABLE_TESTING` with `BUILD_TESTING` (until alpha 5 this was `AMENT_ENABLE_TESTING`) -- replace `catkin_add_gtest` with `ament_add_gtest` -- add a `ament_cmake_gtest` - -##### Linters - -In ROS 2.0 we are working to maintain clean code using linters. -The styles for different languages are defined in our [Developer Guide](Developer-Guide.md). - -If you are starting a project from scratch it is recommended to follow the style guide and turn on the automatic linter unittests by adding these lines just below `if(BUILD_TESTING)` (until alpha 5 this was `AMENT_ENABLE_TESTING`) - -``` cmake -find_package(ament_lint_auto REQUIRED) -ament_lint_auto_find_test_dependencies() -``` - -You will also need to add the following dependencies to your `package.xml`: - -``` xml -ament_lint_auto -ament_lint_common -``` - -#### Continue to use `catkin` in CMake - -ROS 2 uses ament as the build system but for backward compatibility ROS 2 has a package called `catkin` which provides almost the same API as catkin in ROS 1. -In order to use this backward compatibility API the `CMakeLists.txt` must only be updated to call the function `catkin_ament_package()` *after* all targets. - -**NOTE: This has not been implemented yet and is only an idea at the moment. -Due to the amount of changes related to dependencies it has not yet been decided if this compatibility API is useful enough to justify the effort.** - -### Update source code - -#### Messages and services - -The namespace of ROS 2 messages and services uses a subnamespace (`msg` or `srv`) after the package name. -Therefore an include looks like: `#include `. -The C++ type is then named: `my_interfaces::msg::MyMessage`. - -Shared pointer types are provided as typedefs within the message structs: `my_interfaces::msg::MyMessage::SharedPtr` as well as `my_interfaces::msg::MyMessage::ConstSharedPtr`. - -For more details please see the article about the [generated C++ interfaces](http://design.ros2.org/articles/generated_interfaces_cpp.html). - -The migration requires includes to change by: - -- insert the subfolder `msg` between the package name and message datatype -- Change the included filename from CamelCase to underscore separation -- Change from `*.h` to `*.hpp` - -``` cpp -// ROS 1 style is in comments, ROS 2 follows, uncommented. -// # include -#include - -// geometry_msgs::PointStamped point_stamped; -geometry_msgs::msg::PointStamped point_stamped; -``` - -The migration requires code to insert the `msg` namespace into all instances. - -#### Use of service objects -Service callbacks in ROS 2 do not have boolean return values. -Instead of returning false on failures, throwing exceptions is recommended. - -``` cpp -// ROS 1 style is in comments, ROS 2 follows, uncommented. -// #include "nav_msgs/GetMap.h" -#include "nav_msgs/srv/get_map.hpp" - -// bool service_callback( -// nav_msgs::GetMap::Request & request, -// nav_msgs::GetMap::Response & response) -void service_callback( - const std::shared_ptr request, - std::shared_ptr response) -{ - // ... - // return true; // or false for failure -} -``` - -#### Usages of ros::Time - -**TODO There is no direct replacement for ros::Time yet we expect to have one in the future.** - -Under the hood we expect to leverage the cross platform `std::chrono` library. - -Currently for usages of `ros::Time`: - -- replace all instances of `ros::Time` with `builtin_interfaces::msg::Time` -- Convert all instances of `nsec` to `nanosec` -- Convert all single argument double constructors to bare constructor + assignment - -Field values do not get initialized to zero when constructed. -You must make sure to set all values instead of relying on them to be zero. - -Alternatively you can switch to an internal proxy datatype temporarily while waiting for an rclcpp::Time - -#### Usages of ros::Rate - -There is an equivalent type `rclcpp::Rate` object which is basically a drop in replacement for `ros::Rate`. - -#### ROS client library - -**NOTE: to be written** - -#### Boost - -Much of the functionality previously provided by Boost has been integrated into C++11. -As such we would like to take advantage of the new core features and avoid the dependency on boost where possible. - -##### Shared Pointers - -To switch shared pointers from boost to C++11 replace instances of: - -- `#include ` with `` -- `boost::shared_ptr` with `std::shared_ptr` - -There may also be variants such as `weak_ptr` which you want to convert as well. - -Also it is recommended practice to use `using` instead of `typedef`. -`using` has the ability to work better in templated logic. -For details [see here](https://stackoverflow.com/questions/10747810/what-is-the-difference-between-typedef-and-using-in-c11) - -##### Thread/Mutexes - -Another common part of boost used in ROS codebases are mutexes in `boost::thread`. - -- Replace `boost::mutex::scoped_lock` with `std::unique_lock` -- Replace `boost::mutex` with `std::mutex` -- Replace `#include ` with `#include ` - -##### Unordered Map - -Replace: - -- `#include ` with `#include ` -- `boost::unordered_map` with `std::unordered_map` - -##### function - -Replace: - -- `#include ` with `#include ` -- `boost::function` with `std::function` - -## Launch files - -While launch files in ROS 1 are specified using [.xml](http://wiki.ros.org/roslaunch/XML) files ROS 2 uses Python scripts to enable more flexibility (see [launch package](https://github.com/ros2/launch/tree/master/launch)). - -## Example: Converting an existing ROS 1 package to use ROS 2 - -Let's say that we have simple ROS 1 package called `talker` that uses `roscpp` -in one node, called `talker`. -This package is in a catkin workspace, located at `~/ros1_talker`. - -### The ROS 1 code - -Here's the directory layout of our catkin workspace: - -``` bash -$ cd ~/ros1_talker -$ find . -. -./src -./src/talker -./src/talker/package.xml -./src/talker/CMakeLists.txt -./src/talker/talker.cpp -``` - -Here is the content of those three files: - -`src/talker/package.xml`: - -``` xml - - talker - 0.0.0 - talker - Brian Gerkey - Apache 2.0 - catkin - roscpp - std_msgs - roscpp - std_msgs - -``` - -`src/talker/CMakeLists.txt`: - -``` cmake -cmake_minimum_required(VERSION 2.8.3) -project(talker) -find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) -catkin_package() -include_directories(${catkin_INCLUDE_DIRS}) -add_executable(talker talker.cpp) -target_link_libraries(talker ${catkin_LIBRARIES}) -install(TARGETS talker - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) -``` - -`src/talker/talker.cpp`: - -``` cpp -#include -#include "ros/ros.h" -#include "std_msgs/String.h" -int main(int argc, char **argv) -{ - ros::init(argc, argv, "talker"); - ros::NodeHandle n; - ros::Publisher chatter_pub = n.advertise("chatter", 1000); - ros::Rate loop_rate(10); - int count = 0; - std_msgs::String msg; - while (ros::ok()) - { - std::stringstream ss; - ss << "hello world " << count++; - msg.data = ss.str(); - ROS_INFO("%s", msg.data.c_str()); - chatter_pub.publish(msg); - ros::spinOnce(); - loop_rate.sleep(); - } - return 0; -} -``` - -#### Building the ROS 1 code - -We source an environment setup file (in this case for Jade using bash), then we -build our package using `catkin_make install`: - -``` bash -. /opt/ros/jade/setup.bash -cd ~/ros1_talker -catkin_make install -``` - -#### Running the ROS 1 node - -If there's not already one running, we start a `roscore`, first sourcing the -setup file from our `catkin` install tree (the system setup file at -`/opt/ros/jade/setup.bash` would also work here): - -``` bash -. ~/ros1_talker/install/setup.bash -roscore -``` - -In another shell, we run the node from the `catkin` install space using -`rosrun`, again sourcing the setup file first (in this case it must be the one -from our workspace): - -``` bash -. ~/ros1_talker/install/setup.bash -rosrun talker talker -``` - -### Migrating to ROS 2 - -Let's start by creating a new workspace in which to work: - -``` bash -mkdir ~/ros2_talker -cd ~/ros2_talker -``` - -We'll copy the source tree from our ROS 1 package into that workspace, where we can modify it: - -``` bash -mkdir src -cp -a ~/ros1_talker/src/talker src -``` - -Now we'll modify the the C++ code in the node. -The ROS 2 C++ library, called `rclcpp`, provides a different API from that -provided by `roscpp`. -The concepts are very similar between the two libraries, which makes the changes -reasonably straightforward to make. - -#### Included headers - -In place of `ros/ros.h`, which gave us access to the `roscpp` library API, we -need to include `rclcpp/rclcpp.hpp`, which gives us access to the `rclcpp` -library API: - -``` cpp -//#include "ros/ros.h" -#include "rclcpp/rclcpp.hpp" -``` - -To get the `std_msgs/String` message definition, in place of -`std_msgs/String.h`, we need to include `std_msgs/msg/string.hpp`: - -``` cpp -//#include "std_msgs/String.h" -#include "std_msgs/msg/string.hpp" -``` - -#### Changing C++ library calls - -Instead of passing the node's name to the library initialization call, we do -the initialization, then pass the node name to the creation of the node object -(we can use the `auto` keyword because now we're requiring a C++11 compiler): - -``` cpp -// ros::init(argc, argv, "talker"); -// ros::NodeHandle n; - rclcpp::init(argc, argv); - auto node = rclcpp::Node::make_shared("talker"); -``` - -The creation of the publisher and rate objects looks pretty similar, with some -changes to the names of namespace and methods. -For the publisher, instead of an integer queue length argument, we pass a -quality of service (qos) profile, which is a far more flexible way to -controlling how message delivery is handled. -In this example, we just pass the default profile `rmw_qos_profile_default` -(it's global because it's declared in `rmw`, which is written in C and so -doesn't have namespaces). - -``` cpp -// ros::Publisher chatter_pub = n.advertise("chatter", 1000); -// ros::Rate loop_rate(10); - auto chatter_pub = node->create_publisher("chatter", - rmw_qos_profile_default); - rclcpp::Rate loop_rate(10); -``` - -The creation of the outgoing message is different in both the namespace and the -fact that we go ahead and create a shared pointer (this may change in the future -with more publish API that accepts const references): - -``` cpp -// std_msgs::String msg; - auto msg = std::make_shared(); -``` - -In place of `ros::ok()`, we call `rclcpp::ok()`: - -``` cpp -// while (ros::ok()) - while (rclcpp::ok()) -``` - -Inside the publishing loop, we use the `->` operator to access the `data` field -(because now `msg` is a shared pointer): - -``` cpp -// msg.data = ss.str(); - msg->data = ss.str(); -``` - -To print a console message, instead of using `ROS_INFO()`, we use `RCLCPP_INFO()` and its various cousins. The key difference is that `RCLCPP_INFO()` takes a Logger object as the first argument. - -``` cpp -// ROS_INFO("%s", msg.data.c_str()); - RCLCPP_INFO(node->get_logger(), "%s\n", msg->data.c_str()); -``` - -Publishing the message is very similar, the only noticeable difference being -that the publisher is now a shared pointer: - -``` cpp -// chatter_pub.publish(msg); - chatter_pub->publish(msg); -``` - -Spinning (i.e., letting the communications system process any pending -incoming/outgoing messages) is different in that the call now takes the node as -an argument: - -``` cpp -// ros::spinOnce(); - rclcpp::spin_some(node); -``` - -Sleeping using the rate object is unchanged. - -Putting it all together, the new `talker.cpp` looks like this: - -``` cpp -#include -// #include "ros/ros.h" -#include "rclcpp/rclcpp.hpp" -// #include "std_msgs/String.h" -#include "std_msgs/msg/string.hpp" -int main(int argc, char **argv) -{ -// ros::init(argc, argv, "talker"); -// ros::NodeHandle n; - rclcpp::init(argc, argv); - auto node = rclcpp::Node::make_shared("talker"); -// ros::Publisher chatter_pub = n.advertise("chatter", 1000); -// ros::Rate loop_rate(10); - auto chatter_pub = node->create_publisher("chatter", rmw_qos_profile_default); - rclcpp::Rate loop_rate(10); - int count = 0; -// std_msgs::String msg; - auto msg = std::make_shared(); -// while (ros::ok()) - while (rclcpp::ok()) - { - std::stringstream ss; - ss << "hello world " << count++; -// msg.data = ss.str(); - msg->data = ss.str(); -// ROS_INFO("%s", msg.data.c_str()); - RCLCPP_INFO(node->get_logger(), "%s\n", msg->data.c_str()); -// chatter_pub.publish(msg); - chatter_pub->publish(msg); -// ros::spinOnce(); - rclcpp::spin_some(node); - loop_rate.sleep(); - } - return 0; -} -``` - -#### Changing the `package.xml` - -Starting with ROS 2, only version 2 of the `package.xml` format is supported -(this format is also supported in ROS 1, but isn't used by all packages). -We start by specifying the format version in the `package` tag: - -``` xml - - -``` - -ROS 2 uses a newer version of `catkin`, called `ament_cmake`, which we specify in the -`buildtool_depend` tag: - -``` xml - - ament_cmake -``` - -In our build dependencies, instead of `roscpp` we use `rclcpp`, which provides -the C++ API that we use. -We additionally depend on `rmw_implementation`, which pulls in the default -implementation of the `rmw` abstraction layer that allows us to support multiple -DDS implementations (we should consider restructuring / renaming things so that -it's possible to depend on one thing, analogous to `roscpp`): - -``` xml - - rclcpp - rmw_implementation -``` - -We make the same addition in the run dependencies and also update from the -`run_depend` tag to the `exec_depend` tag (part of the upgrade to version 2 of -the package format): - -``` xml - - rclcpp - rmw_implementation - - std_msgs -``` - -We also need to tell the build tool what *kind* of package we are, so that it knows how -to build us. -Because we're using `ament` and CMake, we add the following lines to declare our -build type to be `ament_cmake`: - -``` xml - - ament_cmake - -``` - -Putting it all together, our `package.xml` now looks like this: - -``` xml - - - talker - 0.0.0 - talker - Brian Gerkey - Apache License 2.0 - - ament_cmake - - rclcpp - rmw_implementation - std_msgs - - rclcpp - rmw_implementation - - std_msgs - - ament_cmake - - -``` - -**TODO: show simpler version of this file just using the `` tag, which is -enabled by version 2 of the package format (also supported in `catkin` so, -strictly speaking, orthogonal to ROS 2).** - -#### Changing the CMake code - -ROS 2 relies on a higher version of CMake: - -``` -#cmake_minimum_required(VERSION 2.8.3) -cmake_minimum_required(VERSION 3.5) -``` - -ROS 2 relies on the C++11 standard. -Depending on what compiler you're using, support for C++11 might not be enabled -by default. -Using `gcc` 5.3 (which is what is used on Ubuntu Xenial), we need to enable it -explicitly, which we do by adding this line near the top of the file: - -``` cmake -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -``` - -Using `catkin`, we specify the packages we want to build against by passing them -as `COMPONENTS` arguments when initially finding `catkin` itself. -With `ament_cmake`, we find each package individually, starting with `ament_cmake` -(and adding our new dependency, `rmw_implementation`): - -``` cmake -#find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) -find_package(ament_cmake REQUIRED) -find_package(rclcpp REQUIRED) -find_package(rmw_implementation REQUIRED) -find_package(std_msgs REQUIRED) -``` - -We call `catkin_package()` to auto-generate things like CMake configuration -files for other packages that use our package. -Whereas that call happens *before* specifying targets to build, we now call the -analogous `ament_package()` *after* the targets: - -``` cmake -# catkin_package() -# At the bottom of the file: -ament_package() -``` - -Similarly to how we found each dependent package separately, instead of finding -them as parts of catkin, we also need to add their include directories -separately (see also `ament_target_dependencies()` below, which is a more -concise and more thorough way of handling dependent packages' build flags): - -``` cmake -#include_directories(${catkin_INCLUDE_DIRS}) -include_directories(${rclcpp_INCLUDE_DIRS} - ${rmw_implementation_INCLUDE_DIRS} - ${std_msgs_INCLUDE_DIRS}) -``` - -We do the same to link against our dependent packages' libraries: - -``` cmake -#target_link_libraries(talker ${catkin_LIBRARIES}) -target_link_libraries(talker - ${rclcpp_LIBRARIES} - ${rmw_implementation_LIBRARIES} - ${std_msgs_LIBRARIES}) -``` - -**TODO: explain how `ament_target_dependencies()` simplifies the above steps and -is also better (also handling `*_DEFINITIONS`, doing target-specific include -directories, etc.).** - -For installation, `catkin` defines variables like -`CATKIN_PACKAGE_BIN_DESTINATION`. -With `ament_cmake`, we just give a path relative to the installation root, like `bin` -for executables (this is in part because we don't yet have an equivalent of -`rosrun`): - -``` cmake -#install(TARGETS talker -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) -install(TARGETS talker RUNTIME DESTINATION bin) -``` - -Putting it all together, the new `CMakeLists.txt` looks like this: - -``` cmake -#cmake_minimum_required(VERSION 2.8.3) -cmake_minimum_required(VERSION 3.5) -project(talker) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -#find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) -find_package(ament_cmake REQUIRED) -find_package(rclcpp REQUIRED) -find_package(rmw_implementation REQUIRED) -find_package(std_msgs REQUIRED) -#catkin_package() -#include_directories(${catkin_INCLUDE_DIRS}) -include_directories(${rclcpp_INCLUDE_DIRS} - ${rmw_implementation_INCLUDE_DIRS} - ${std_msgs_INCLUDE_DIRS}) -add_executable(talker talker.cpp) -#target_link_libraries(talker ${catkin_LIBRARIES}) -target_link_libraries(talker - ${rclcpp_LIBRARIES} - ${rmw_implementation_LIBRARIES} - ${std_msgs_LIBRARIES}) -#install(TARGETS talker -# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) -install(TARGETS talker RUNTIME DESTINATION bin) -ament_package() -``` - -**TODO: Show what this would look like with `ament_auto`.** - -#### Building the ROS 2 code - -We source an environment setup file (in this case the one generated by following -the ROS 2 installation tutorial, which builds in `~/ros2_ws`, then we build our -package using `colcon build`: - -``` bash -. ~/ros2_ws/install/setup.bash -cd ~/ros2_talker -colcon build -``` - -#### Running the ROS 2 node - -Because we installed the `talker` executable into `bin`, after sourcing the -setup file, from our install tree, we can invoke it by name directly -(also, there is not yet a ROS 2 equivalent for `rosrun`): - -``` bash -. ~/ros2_ws/install/setup.bash -talker -``` - -## Licensing - -In ROS 2 our recommended license is the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0) -In ROS 1 our recommended license was the [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -For any new project we recommend using the Apache 2.0 License, whether ROS 1 or ROS 2. - -However when migrating code from ROS 1 to ROS 2 we cannot simply change the license, the existing license must be preserved for any preexisting contributions. - -To that end if a package is being migrated we recommend keeping the existing license and continuing to contributing to that package under the existing OSI license, which we expect to be the BSD license for core elements. - -This will keep things clear and easy to understand. - -### Changing the License - -It is possible to change the license, however you will need to contact all the contributors and get permission. -For most packages this is likely to be a significant effort and not worth considering. -If the package as a small set of contributors then this may be feasible. - diff --git a/Migration-Guide.rst b/Migration-Guide.rst new file mode 100644 index 00000000000..b40b5470dcd --- /dev/null +++ b/Migration-Guide.rst @@ -0,0 +1,893 @@ + +Migration guide from ROS 1 +========================== + +This article describes the high-level steps to migrate a ROS 1 package to ROS 2. +It does not aim to be a step-by-step migration instruction and is not considered the *final* "solution". +Future versions will aim to make migration smoother and less effort up to the point that maintaining a single package from the same branch for ROS 1 as well as ROS 2 + +Migration Steps: + + +* `Package Manifests <#Package-manifests>` +* `Message and service definitions <#Message-and-service-definitions>` +* `Source Code <#Update-source-code>` +* `Build System <#Build-system>` +* `Launch Files <#Launch-files>_ +* `Licensing <#licensing>` + +Prerequisite +------------ + +Before being able to migrate a ROS 1 package to ROS 2 all of its dependencies must be available in ROS 2. + +Migration steps +--------------- + +Package manifests +^^^^^^^^^^^^^^^^^ + +ROS 2 only support the format 2 of the package specification which is defined in `REP 140 `__. +Therefore the ``package.xml`` file must be updated to format 2 if it uses format 1. +Since ROS 1 support both formats (1 as well as 2) it is safe to perform that conversion in the ROS 1 package. + +Some packages might have different names in ROS 2 so the dependencies might need to be updated accordingly. + +Message and service definitions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Message files must end in ``.msg`` and must be located in the subfolder ``msg``. +Service files must end in ``.srv`` and must be located in the subfolder ``srv``. + +These files might need to be updated to comply with the `ROS Interface definition `__. +Some primitive types have been removed and the types ``duration`` and ``time`` which were builtin types in ROS 1 have been replaced with normal message definitions and must be used from the `\ ``builtin_interfaces`` `__ package. +Also some naming conventions are stricter then in ROS 1. + +In your ``package.xml`` you will need to add: + + +* ``rosidl_default_generators`` +* ``rosidl_default_runtime`` +* For each dependent message package add ``message_package`` + +In your ``CMakeLists.txt``\ : + +Start by enabling C++11 + +.. code-block:: cmake + + if(NOT WIN32) + add_definitions(-std=c++11) + endif() + + +* ``find_package(rosidl_default_generators REQUIRED)`` +* For each dependent message package add ``find_package(message_package REQUIRED)`` and replace the cmake function call to ``generate_messages`` with ``rosidl_generate_interfaces`` + +This will replace ``add_message_files`` and ``add_service_files`` listing of all the message and service files, which can be removed. + +Build system +^^^^^^^^^^^^ + +The build system in ROS 2 is called `ament `__. + +Build tool +~~~~~~~~~~ + +Instead of using ``catkin_make``\ , ``catkin_make_isolated`` or ``catkin build`` ROS 2 uses the command line tool `colcon `__ to build and install a set of packages. + +Pure Python package +~~~~~~~~~~~~~~~~~~~ + +If the ROS 1 package uses CMake only to invoke the ``setup.py`` file and does not contain anything beside Python code (e.g. also no messages, services, etc.) it should be converted into a pure Python package in ROS 2: + + +* + Update or add the build type in the ``package.xml`` file: + + .. code-block:: xml + + + ament_python + + +* + Remove the ``CMakeLists.txt`` file + +* + Update the ``setup.py`` file to be a standard Python setup script + +ROS 2 supports Python 3 only. +While each package can choose to also support Python 2 it must invoke executables with Python 3 if it uses any API provided by other ROS 2 packages. + +Update the *CMakeLists.txt* to use *ament_cmake* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Apply the following changes to use ``ament_cmake`` instead of ``catkin``\ : + + +* + Set the build type in the ``package.xml`` file export section: + + .. code-block:: xml + + + ament_cmake + + +* + Replace the ``find_package`` invocation with ``catkin`` and the ``COMPONENTS`` with: + + .. code-block:: cmake + + find_package(ament_cmake REQUIRED) + find_package(component1 REQUIRED) + # ... + find_package(componentN REQUIRED) + +* + Move and update the ``catkin_package`` invocation with: + + + * + Invoke ``ament_package`` instead but **after** all targets have been registered. + + * + The only valid argument for `ament_package `__ is ``CONFIG_EXTRAS``. + All other arguments are covered by separate functions which all need to be invoked *before* ``ament_package``. + + * + **TODO document ament_export_interfaces?** + +* + Replace the invocation of ``add_message_files``\ , ``add_service_files`` and ``generate_messages`` with `rosidl_generate_interfaces `__. + + + * + The first argument is the ``target_name``. + If you're building just one library it's ``${PROJECT_NAME}`` + + * + Followed by the list of message filenames, relative to the package root. + + + * If you will be using the list of filenames multiple times, it is recommended to compose a list of message files and pass the list to the function for clarity. + + * + The final multi-value-keyword argument fpr ``generate_messages`` is ``DEPENDENCIES`` which requires the list of dependent message packages. + + .. code-block:: cmake + + rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + DEPENDENCIES std_msgs + ) + +* + Remove any occurrences of the *devel space*. + Related CMake variables like ``CATKIN_DEVEL_PREFIX`` do not exist anymore. + + + * The ``CATKIN_DEPENDS`` and ``DEPENDS`` arguments are passed to the new function `ament_export_dependencies `__. + +* + Replace the invocation of ``add_message_files``\ , ``add_service_files`` and ``generate_messages`` with `rosidl_generate_interfaces `__. + +* + Remove any occurrences of the *devel space*. + Related CMake variables like ``CATKIN_DEVEL_PREFIX`` do not exist anymore. + + + * ``CATKIN_GLOBAL_BIN_DESTINATION``\ : ``bin`` + * ``CATKIN_GLOBAL_INCLUDE_DESTINATION``\ : ``include`` + * ``CATKIN_GLOBAL_LIB_DESTINATION``\ : ``lib`` + * ``CATKIN_GLOBAL_LIBEXEC_DESTINATION``\ : ``lib`` + * ``CATKIN_GLOBAL_SHARE_DESTINATION``\ : ``share`` + * ``CATKIN_PACKAGE_BIN_DESTINATION``\ : ``lib/${PROJECT_NAME}`` + * ``CATKIN_PACKAGE_INCLUDE_DESTINATION``\ : ``include/${PROJECT_NAME}`` + * ``CATKIN_PACKAGE_LIB_DESTINATION``\ : ``lib`` + * ``CATKIN_PACKAGE_SHARE_DESTINATION``\ : ``share/${PROJECT_NAME}`` + +Unit tests +~~~~~~~~~~ + +If you are using gtest + + +* replace ``CATKIN_ENABLE_TESTING`` with ``BUILD_TESTING`` (until alpha 5 this was ``AMENT_ENABLE_TESTING``\ ) +* replace ``catkin_add_gtest`` with ``ament_add_gtest`` +* add a ``ament_cmake_gtest`` + +Linters +""""""" + +In ROS 2.0 we are working to maintain clean code using linters. +The styles for different languages are defined in our `Developer Guide `. + +If you are starting a project from scratch it is recommended to follow the style guide and turn on the automatic linter unittests by adding these lines just below ``if(BUILD_TESTING)`` (until alpha 5 this was ``AMENT_ENABLE_TESTING``\ ) + +.. code-block:: cmake + + find_package(ament_lint_auto REQUIRED) + ament_lint_auto_find_test_dependencies() + +You will also need to add the following dependencies to your ``package.xml``\ : + +.. code-block:: xml + + ament_lint_auto + ament_lint_common + +Continue to use ``catkin`` in CMake +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +ROS 2 uses ament as the build system but for backward compatibility ROS 2 has a package called ``catkin`` which provides almost the same API as catkin in ROS 1. +In order to use this backward compatibility API the ``CMakeLists.txt`` must only be updated to call the function ``catkin_ament_package()`` *after* all targets. + +**NOTE: This has not been implemented yet and is only an idea at the moment. +Due to the amount of changes related to dependencies it has not yet been decided if this compatibility API is useful enough to justify the effort.** + +Update source code +^^^^^^^^^^^^^^^^^^ + +Messages and services +~~~~~~~~~~~~~~~~~~~~~ + +The namespace of ROS 2 messages and services uses a subnamespace (\ ``msg`` or ``srv``\ ) after the package name. +Therefore an include looks like: ``#include ``. +The C++ type is then named: ``my_interfaces::msg::MyMessage``. + +Shared pointer types are provided as typedefs within the message structs: ``my_interfaces::msg::MyMessage::SharedPtr`` as well as ``my_interfaces::msg::MyMessage::ConstSharedPtr``. + +For more details please see the article about the `generated C++ interfaces `__. + +The migration requires includes to change by: + + +* insert the subfolder ``msg`` between the package name and message datatype +* Change the included filename from CamelCase to underscore separation +* Change from ``*.h`` to ``*.hpp`` + +.. code-block:: cpp + + // ROS 1 style is in comments, ROS 2 follows, uncommented. + // # include + #include + + // geometry_msgs::PointStamped point_stamped; + geometry_msgs::msg::PointStamped point_stamped; + +The migration requires code to insert the ``msg`` namespace into all instances. + +Use of service objects +~~~~~~~~~~~~~~~~~~~~~~ + +Service callbacks in ROS 2 do not have boolean return values. +Instead of returning false on failures, throwing exceptions is recommended. + +.. code-block:: cpp + + // ROS 1 style is in comments, ROS 2 follows, uncommented. + // #include "nav_msgs/GetMap.h" + #include "nav_msgs/srv/get_map.hpp" + + // bool service_callback( + // nav_msgs::GetMap::Request & request, + // nav_msgs::GetMap::Response & response) + void service_callback( + const std::shared_ptr request, + std::shared_ptr response) + { + // ... + // return true; // or false for failure + } + +Usages of ros::Time +~~~~~~~~~~~~~~~~~~~ + +**TODO There is no direct replacement for ros::Time yet we expect to have one in the future.** + +Under the hood we expect to leverage the cross platform ``std::chrono`` library. + +Currently for usages of ``ros::Time``\ : + + +* replace all instances of ``ros::Time`` with ``builtin_interfaces::msg::Time`` +* Convert all instances of ``nsec`` to ``nanosec`` +* Convert all single argument double constructors to bare constructor + assignment + +Field values do not get initialized to zero when constructed. +You must make sure to set all values instead of relying on them to be zero. + +Alternatively you can switch to an internal proxy datatype temporarily while waiting for an rclcpp::Time + +Usages of ros::Rate +~~~~~~~~~~~~~~~~~~~ + +There is an equivalent type ``rclcpp::Rate`` object which is basically a drop in replacement for ``ros::Rate``. + +ROS client library +~~~~~~~~~~~~~~~~~~ + +**NOTE: to be written** + +Boost +~~~~~ + +Much of the functionality previously provided by Boost has been integrated into C++11. +As such we would like to take advantage of the new core features and avoid the dependency on boost where possible. + +Shared Pointers +""""""""""""""" + +To switch shared pointers from boost to C++11 replace instances of: + + +* ``#include `` with ```` +* ``boost::shared_ptr`` with ``std::shared_ptr`` + +There may also be variants such as ``weak_ptr`` which you want to convert as well. + +Also it is recommended practice to use ``using`` instead of ``typedef``. +``using`` has the ability to work better in templated logic. +For details `see here `__ + +Thread/Mutexes +"""""""""""""" + +Another common part of boost used in ROS codebases are mutexes in ``boost::thread``. + + +* Replace ``boost::mutex::scoped_lock`` with ``std::unique_lock`` +* Replace ``boost::mutex`` with ``std::mutex`` +* Replace ``#include `` with ``#include `` + +Unordered Map +""""""""""""" + +Replace: + + +* ``#include `` with ``#include `` +* ``boost::unordered_map`` with ``std::unordered_map`` + +function +"""""""" + +Replace: + + +* ``#include `` with ``#include `` +* ``boost::function`` with ``std::function`` + +Launch files +------------ + +While launch files in ROS 1 are specified using `.xml `__ files ROS 2 uses Python scripts to enable more flexibility (see `launch package `__\ ). + +Example: Converting an existing ROS 1 package to use ROS 2 +---------------------------------------------------------- + +Let's say that we have simple ROS 1 package called ``talker`` that uses ``roscpp`` +in one node, called ``talker``. +This package is in a catkin workspace, located at ``~/ros1_talker``. + +The ROS 1 code +^^^^^^^^^^^^^^ + +Here's the directory layout of our catkin workspace: + +.. code-block:: bash + + $ cd ~/ros1_talker + $ find . + . + ./src + ./src/talker + ./src/talker/package.xml + ./src/talker/CMakeLists.txt + ./src/talker/talker.cpp + +Here is the content of those three files: + +``src/talker/package.xml``\ : + +.. code-block:: xml + + + talker + 0.0.0 + talker + Brian Gerkey + Apache 2.0 + catkin + roscpp + std_msgs + roscpp + std_msgs + + +``src/talker/CMakeLists.txt``\ : + +.. code-block:: cmake + + cmake_minimum_required(VERSION 2.8.3) + project(talker) + find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) + catkin_package() + include_directories(${catkin_INCLUDE_DIRS}) + add_executable(talker talker.cpp) + target_link_libraries(talker ${catkin_LIBRARIES}) + install(TARGETS talker + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + +``src/talker/talker.cpp``\ : + +.. code-block:: cpp + + #include + #include "ros/ros.h" + #include "std_msgs/String.h" + int main(int argc, char **argv) + { + ros::init(argc, argv, "talker"); + ros::NodeHandle n; + ros::Publisher chatter_pub = n.advertise("chatter", 1000); + ros::Rate loop_rate(10); + int count = 0; + std_msgs::String msg; + while (ros::ok()) + { + std::stringstream ss; + ss << "hello world " << count++; + msg.data = ss.str(); + ROS_INFO("%s", msg.data.c_str()); + chatter_pub.publish(msg); + ros::spinOnce(); + loop_rate.sleep(); + } + return 0; + } + +Building the ROS 1 code +~~~~~~~~~~~~~~~~~~~~~~~ + +We source an environment setup file (in this case for Jade using bash), then we +build our package using ``catkin_make install``\ : + +.. code-block:: bash + + . /opt/ros/jade/setup.bash + cd ~/ros1_talker + catkin_make install + +Running the ROS 1 node +~~~~~~~~~~~~~~~~~~~~~~ + +If there's not already one running, we start a ``roscore``\ , first sourcing the +setup file from our ``catkin`` install tree (the system setup file at +``/opt/ros/jade/setup.bash`` would also work here): + +.. code-block:: bash + + . ~/ros1_talker/install/setup.bash + roscore + +In another shell, we run the node from the ``catkin`` install space using +``rosrun``\ , again sourcing the setup file first (in this case it must be the one +from our workspace): + +.. code-block:: bash + + . ~/ros1_talker/install/setup.bash + rosrun talker talker + +Migrating to ROS 2 +^^^^^^^^^^^^^^^^^^ + +Let's start by creating a new workspace in which to work: + +.. code-block:: bash + + mkdir ~/ros2_talker + cd ~/ros2_talker + +We'll copy the source tree from our ROS 1 package into that workspace, where we can modify it: + +.. code-block:: bash + + mkdir src + cp -a ~/ros1_talker/src/talker src + +Now we'll modify the the C++ code in the node. +The ROS 2 C++ library, called ``rclcpp``\ , provides a different API from that +provided by ``roscpp``. +The concepts are very similar between the two libraries, which makes the changes +reasonably straightforward to make. + +Included headers +~~~~~~~~~~~~~~~~ + +In place of ``ros/ros.h``\ , which gave us access to the ``roscpp`` library API, we +need to include ``rclcpp/rclcpp.hpp``\ , which gives us access to the ``rclcpp`` +library API: + +.. code-block:: cpp + + //#include "ros/ros.h" + #include "rclcpp/rclcpp.hpp" + +To get the ``std_msgs/String`` message definition, in place of +``std_msgs/String.h``\ , we need to include ``std_msgs/msg/string.hpp``\ : + +.. code-block:: cpp + + //#include "std_msgs/String.h" + #include "std_msgs/msg/string.hpp" + +Changing C++ library calls +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of passing the node's name to the library initialization call, we do +the initialization, then pass the node name to the creation of the node object +(we can use the ``auto`` keyword because now we're requiring a C++11 compiler): + +.. code-block:: cpp + + // ros::init(argc, argv, "talker"); + // ros::NodeHandle n; + rclcpp::init(argc, argv); + auto node = rclcpp::Node::make_shared("talker"); + +The creation of the publisher and rate objects looks pretty similar, with some +changes to the names of namespace and methods. +For the publisher, instead of an integer queue length argument, we pass a +quality of service (qos) profile, which is a far more flexible way to +controlling how message delivery is handled. +In this example, we just pass the default profile ``rmw_qos_profile_default`` +(it's global because it's declared in ``rmw``\ , which is written in C and so +doesn't have namespaces). + +.. code-block:: cpp + + // ros::Publisher chatter_pub = n.advertise("chatter", 1000); + // ros::Rate loop_rate(10); + auto chatter_pub = node->create_publisher("chatter", + rmw_qos_profile_default); + rclcpp::Rate loop_rate(10); + +The creation of the outgoing message is different in both the namespace and the +fact that we go ahead and create a shared pointer (this may change in the future +with more publish API that accepts const references): + +.. code-block:: cpp + + // std_msgs::String msg; + auto msg = std::make_shared(); + +In place of ``ros::ok()``\ , we call ``rclcpp::ok()``\ : + +.. code-block:: cpp + + // while (ros::ok()) + while (rclcpp::ok()) + +Inside the publishing loop, we use the ``->`` operator to access the ``data`` field +(because now ``msg`` is a shared pointer): + +.. code-block:: cpp + + // msg.data = ss.str(); + msg->data = ss.str(); + +To print a console message, instead of using ``ROS_INFO()``\ , we use ``RCLCPP_INFO()`` and its various cousins. The key difference is that ``RCLCPP_INFO()`` takes a Logger object as the first argument. + +.. code-block:: cpp + + // ROS_INFO("%s", msg.data.c_str()); + RCLCPP_INFO(node->get_logger(), "%s\n", msg->data.c_str()); + +Publishing the message is very similar, the only noticeable difference being +that the publisher is now a shared pointer: + +.. code-block:: cpp + + // chatter_pub.publish(msg); + chatter_pub->publish(msg); + +Spinning (i.e., letting the communications system process any pending +incoming/outgoing messages) is different in that the call now takes the node as +an argument: + +.. code-block:: cpp + + // ros::spinOnce(); + rclcpp::spin_some(node); + +Sleeping using the rate object is unchanged. + +Putting it all together, the new ``talker.cpp`` looks like this: + +.. code-block:: cpp + + #include + // #include "ros/ros.h" + #include "rclcpp/rclcpp.hpp" + // #include "std_msgs/String.h" + #include "std_msgs/msg/string.hpp" + int main(int argc, char **argv) + { + // ros::init(argc, argv, "talker"); + // ros::NodeHandle n; + rclcpp::init(argc, argv); + auto node = rclcpp::Node::make_shared("talker"); + // ros::Publisher chatter_pub = n.advertise("chatter", 1000); + // ros::Rate loop_rate(10); + auto chatter_pub = node->create_publisher("chatter", rmw_qos_profile_default); + rclcpp::Rate loop_rate(10); + int count = 0; + // std_msgs::String msg; + auto msg = std::make_shared(); + // while (ros::ok()) + while (rclcpp::ok()) + { + std::stringstream ss; + ss << "hello world " << count++; + // msg.data = ss.str(); + msg->data = ss.str(); + // ROS_INFO("%s", msg.data.c_str()); + RCLCPP_INFO(node->get_logger(), "%s\n", msg->data.c_str()); + // chatter_pub.publish(msg); + chatter_pub->publish(msg); + // ros::spinOnce(); + rclcpp::spin_some(node); + loop_rate.sleep(); + } + return 0; + } + +Changing the ``package.xml`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Starting with ROS 2, only version 2 of the ``package.xml`` format is supported +(this format is also supported in ROS 1, but isn't used by all packages). +We start by specifying the format version in the ``package`` tag: + +.. code-block:: xml + + + + +ROS 2 uses a newer version of ``catkin``\ , called ``ament_cmake``\ , which we specify in the +``buildtool_depend`` tag: + +.. code-block:: xml + + + ament_cmake + +In our build dependencies, instead of ``roscpp`` we use ``rclcpp``\ , which provides +the C++ API that we use. +We additionally depend on ``rmw_implementation``\ , which pulls in the default +implementation of the ``rmw`` abstraction layer that allows us to support multiple +DDS implementations (we should consider restructuring / renaming things so that +it's possible to depend on one thing, analogous to ``roscpp``\ ): + +.. code-block:: xml + + + rclcpp + rmw_implementation + +We make the same addition in the run dependencies and also update from the +``run_depend`` tag to the ``exec_depend`` tag (part of the upgrade to version 2 of +the package format): + +.. code-block:: xml + + + rclcpp + rmw_implementation + + std_msgs + +We also need to tell the build tool what *kind* of package we are, so that it knows how +to build us. +Because we're using ``ament`` and CMake, we add the following lines to declare our +build type to be ``ament_cmake``\ : + +.. code-block:: xml + + + ament_cmake + + +Putting it all together, our ``package.xml`` now looks like this: + +.. code-block:: xml + + + + talker + 0.0.0 + talker + Brian Gerkey + Apache License 2.0 + + ament_cmake + + rclcpp + rmw_implementation + std_msgs + + rclcpp + rmw_implementation + + std_msgs + + ament_cmake + + + +**TODO: show simpler version of this file just using the ```` tag, which is +enabled by version 2 of the package format (also supported in ``catkin`` so, +strictly speaking, orthogonal to ROS 2).** + +Changing the CMake code +~~~~~~~~~~~~~~~~~~~~~~~ + +ROS 2 relies on a higher version of CMake: + +.. code-block:: + + #cmake_minimum_required(VERSION 2.8.3) + cmake_minimum_required(VERSION 3.5) + +ROS 2 relies on the C++11 standard. +Depending on what compiler you're using, support for C++11 might not be enabled +by default. +Using ``gcc`` 5.3 (which is what is used on Ubuntu Xenial), we need to enable it +explicitly, which we do by adding this line near the top of the file: + +.. code-block:: cmake + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +Using ``catkin``\ , we specify the packages we want to build against by passing them +as ``COMPONENTS`` arguments when initially finding ``catkin`` itself. +With ``ament_cmake``\ , we find each package individually, starting with ``ament_cmake`` +(and adding our new dependency, ``rmw_implementation``\ ): + +.. code-block:: cmake + + #find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) + find_package(ament_cmake REQUIRED) + find_package(rclcpp REQUIRED) + find_package(rmw_implementation REQUIRED) + find_package(std_msgs REQUIRED) + +We call ``catkin_package()`` to auto-generate things like CMake configuration +files for other packages that use our package. +Whereas that call happens *before* specifying targets to build, we now call the +analogous ``ament_package()`` *after* the targets: + +.. code-block:: cmake + + # catkin_package() + # At the bottom of the file: + ament_package() + +Similarly to how we found each dependent package separately, instead of finding +them as parts of catkin, we also need to add their include directories +separately (see also ``ament_target_dependencies()`` below, which is a more +concise and more thorough way of handling dependent packages' build flags): + +.. code-block:: cmake + + #include_directories(${catkin_INCLUDE_DIRS}) + include_directories(${rclcpp_INCLUDE_DIRS} + ${rmw_implementation_INCLUDE_DIRS} + ${std_msgs_INCLUDE_DIRS}) + +We do the same to link against our dependent packages' libraries: + +.. code-block:: cmake + + #target_link_libraries(talker ${catkin_LIBRARIES}) + target_link_libraries(talker + ${rclcpp_LIBRARIES} + ${rmw_implementation_LIBRARIES} + ${std_msgs_LIBRARIES}) + +**TODO: explain how ``ament_target_dependencies()`` simplifies the above steps and +is also better (also handling ``*_DEFINITIONS``\ , doing target-specific include +directories, etc.).** + +For installation, ``catkin`` defines variables like +``CATKIN_PACKAGE_BIN_DESTINATION``. +With ``ament_cmake``\ , we just give a path relative to the installation root, like ``bin`` +for executables (this is in part because we don't yet have an equivalent of +``rosrun``\ ): + +.. code-block:: cmake + + #install(TARGETS talker + # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + install(TARGETS talker RUNTIME DESTINATION bin) + +Putting it all together, the new ``CMakeLists.txt`` looks like this: + +.. code-block:: cmake + + #cmake_minimum_required(VERSION 2.8.3) + cmake_minimum_required(VERSION 3.5) + project(talker) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + #find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) + find_package(ament_cmake REQUIRED) + find_package(rclcpp REQUIRED) + find_package(rmw_implementation REQUIRED) + find_package(std_msgs REQUIRED) + #catkin_package() + #include_directories(${catkin_INCLUDE_DIRS}) + include_directories(${rclcpp_INCLUDE_DIRS} + ${rmw_implementation_INCLUDE_DIRS} + ${std_msgs_INCLUDE_DIRS}) + add_executable(talker talker.cpp) + #target_link_libraries(talker ${catkin_LIBRARIES}) + target_link_libraries(talker + ${rclcpp_LIBRARIES} + ${rmw_implementation_LIBRARIES} + ${std_msgs_LIBRARIES}) + #install(TARGETS talker + # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) + install(TARGETS talker RUNTIME DESTINATION bin) + ament_package() + +**TODO: Show what this would look like with ``ament_auto``.** + +Building the ROS 2 code +~~~~~~~~~~~~~~~~~~~~~~~ + +We source an environment setup file (in this case the one generated by following +the ROS 2 installation tutorial, which builds in ``~/ros2_ws``\ , then we build our +package using ``colcon build``\ : + +.. code-block:: bash + + . ~/ros2_ws/install/setup.bash + cd ~/ros2_talker + colcon build + +Running the ROS 2 node +~~~~~~~~~~~~~~~~~~~~~~ + +Because we installed the ``talker`` executable into ``bin``\ , after sourcing the +setup file, from our install tree, we can invoke it by name directly +(also, there is not yet a ROS 2 equivalent for ``rosrun``\ ): + +.. code-block:: bash + + . ~/ros2_ws/install/setup.bash + talker + +Licensing +--------- + +In ROS 2 our recommended license is the `Apache 2.0 License `__ +In ROS 1 our recommended license was the `3-Clause BSD License `__ + +For any new project we recommend using the Apache 2.0 License, whether ROS 1 or ROS 2. + +However when migrating code from ROS 1 to ROS 2 we cannot simply change the license, the existing license must be preserved for any preexisting contributions. + +To that end if a package is being migrated we recommend keeping the existing license and continuing to contributing to that package under the existing OSI license, which we expect to be the BSD license for core elements. + +This will keep things clear and easy to understand. + +Changing the License +^^^^^^^^^^^^^^^^^^^^ + +It is possible to change the license, however you will need to contact all the contributors and get permission. +For most packages this is likely to be a significant effort and not worth considering. +If the package as a small set of contributors then this may be feasible. diff --git a/New-features-in-ROS-2-interfaces-(msg-srv).md b/New-features-in-ROS-2-interfaces-(msg-srv).md deleted file mode 100644 index 6715debe728..00000000000 --- a/New-features-in-ROS-2-interfaces-(msg-srv).md +++ /dev/null @@ -1,14 +0,0 @@ -# New features in ROS 2 interfaces - -**INCOMPLETE** - -The [ROS 2 interface definition language](About-ROS-Interfaces.md), or IDL, is closely related to the [ROS 1 IDL](http://wiki.ros.org/msg). -Most existing ROS 1 `.msg` and `.srv` files should be usable as-is with ROS 2. -Atop that existing feature set, the ROS 2 IDL introduces some new features, namely: -* **bounded arrays**: Whereas the ROS 1 IDL allows unbounded arrays (e.g., `int32[] foo`) and fixed-size arrays (e.g., `int32[5] bar`), the ROS 2 IDL further allows bounded arrays (e.g., `int32[<=5] bat`). -There are use cases in which it's important to be able to place an upper bound on the size of an array without committing to always using that much space (e.g., in a real-time system in which you need to preallocate all memory that will be used during execution). -* **bounded strings**: Whereas the ROS 1 IDL allows unbounded strings (e.g., `string foo`), the ROS 2 IDL further allows bounded strings (e.g., `string<=5 bar`). -* **default values**: Whereas the ROS 1 IDL allows constant fields (e.g., `int32 X=123`), the ROS 2 IDL further allows default values to be specified (e.g., `int32 X 123`). -The default value is used when constructing a message/service object and can be subsequently overridden by assigning to the field. -*Note: in ROS Ardent, default values are not supported for complex types or string arrays or strings with encoding. -*Note: in ROS Bouncy, default values are not supported for complex types or string with encoding. diff --git a/New-features-in-ROS-2-interfaces-(msg-srv).rst b/New-features-in-ROS-2-interfaces-(msg-srv).rst new file mode 100644 index 00000000000..b5ca6a37fd4 --- /dev/null +++ b/New-features-in-ROS-2-interfaces-(msg-srv).rst @@ -0,0 +1,17 @@ + +New features in ROS 2 interfaces +================================ + +**INCOMPLETE** + +The `ROS 2 interface definition language `_\ , or IDL, is closely related to the `ROS 1 IDL `__. +Most existing ROS 1 ``.msg`` and ``.srv`` files should be usable as-is with ROS 2. +Atop that existing feature set, the ROS 2 IDL introduces some new features, namely: + + +* **bounded arrays**\ : Whereas the ROS 1 IDL allows unbounded arrays (e.g., ``int32[] foo``\ ) and fixed-size arrays (e.g., ``int32[5] bar``\ ), the ROS 2 IDL further allows bounded arrays (e.g., ``int32[<=5] bat``\ ). + There are use cases in which it's important to be able to place an upper bound on the size of an array without committing to always using that much space (e.g., in a real-time system in which you need to preallocate all memory that will be used during execution). +* **bounded strings**\ : Whereas the ROS 1 IDL allows unbounded strings (e.g., ``string foo``\ ), the ROS 2 IDL further allows bounded strings (e.g., ``string<=5 bar``\ ). +* **default values**\ : Whereas the ROS 1 IDL allows constant fields (e.g., ``int32 X=123``\ ), the ROS 2 IDL further allows default values to be specified (e.g., ``int32 X 123``\ ). + The default value is used when constructing a message/service object and can be subsequently overridden by assigning to the field. + *Note: in ROS Ardent, default values are not supported for complex types or string arrays or strings with encoding.*\ Note: in ROS Bouncy, default values are not supported for complex types or string with encoding. diff --git a/Node-arguments.md b/Node-arguments.md deleted file mode 100644 index a0aaa17fa83..00000000000 --- a/Node-arguments.md +++ /dev/null @@ -1,69 +0,0 @@ -# Overview - -All ROS nodes take a set of arguments that allow various properties to be reconfigured. -Examples include configuring the name/namespace of the node, topic/service names used, and parameters on the node. - -_Note: all features on this page are only available as of the ROS 2 Bouncy release._ - -## Name remapping - -Names within a node (e.g. topics/services) can be remapped using the syntax `:=`. -The name/namespace of the node itself can be remapped using `__node:=` and `__ns:=`. - -Note that these remappings are "static" remappings, in that they apply for the lifetime of the node. -"Dynamic" remapping of names after nodes have been started is not yet supported. - -See [this design doc](http://design.ros2.org/articles/static_remapping.html) for more details on remapping arguments (not all functionality is available yet). - -### Example - -The following invocation will cause the `talker` node to be started under the node name `my_talker`, publishing on the topic named `my_topic` instead of the default of `chatter`. -The namespace, which must start with a forward slash, is set to `/demo`, which means that topics are created in that namespace (`/demo/my_topic`), as opposed to globally (`/my_topic`). -``` -ros2 run demo_nodes_cpp talker __ns:=/demo __node:=my_talker chatter:=my_topic -``` - -#### Passing remapping arguments to specific nodes - -If multiple nodes are being run within a single process (e.g. using [Composition](Composition.md)), remapping arguments can be passed to a specific node using its name as a prefix. -For example, the following will pass the remapping arguments to the specified nodes: - -``` -ros2 run composition manual_composition talker:__node:=my_talker listener:__node:=my_listener -``` - -## Logger configuration - -See [the logging page](Logging.md#command-line-configuration-of-the-default-severity-level). - -## Parameters - -_Parameters are currently only supported for C++ nodes._ - -Setting parameters from the command-line is currently supported in the form of yaml files. - -[See here](https://github.com/ros2/rcl/tree/master/rcl_yaml_param_parser) for examples of the yaml file syntax. As an example, save the following as `demo_params.yaml` - -```yaml -talker: - ros__parameters: - some_int: 42 - a_string: "Hello world" - some_lists: - some_integers: [1, 2, 3, 4] - some_doubles : [3.14, 2.718] -``` - -Then run the following: -``` -ros2 run demo_nodes_cpp talker __params:=demo_params.yaml -``` - -Other nodes will be able to retrieve the parameter values, e.g.: -``` -$ ros2 param list talker - a_string - some_int - some_lists.some_doubles - some_lists.some_integers -``` \ No newline at end of file diff --git a/Node-arguments.rst b/Node-arguments.rst new file mode 100644 index 00000000000..25c3d1153ab --- /dev/null +++ b/Node-arguments.rst @@ -0,0 +1,79 @@ + +Overview +======== + +All ROS nodes take a set of arguments that allow various properties to be reconfigured. +Examples include configuring the name/namespace of the node, topic/service names used, and parameters on the node. + +*Note: all features on this page are only available as of the ROS 2 Bouncy release.* + +Name remapping +-------------- + +Names within a node (e.g. topics/services) can be remapped using the syntax ``:=``. +The name/namespace of the node itself can be remapped using ``__node:=`` and ``__ns:=``. + +Note that these remappings are "static" remappings, in that they apply for the lifetime of the node. +"Dynamic" remapping of names after nodes have been started is not yet supported. + +See `this design doc `__ for more details on remapping arguments (not all functionality is available yet). + +Example +^^^^^^^ + +The following invocation will cause the ``talker`` node to be started under the node name ``my_talker``\ , publishing on the topic named ``my_topic`` instead of the default of ``chatter``. +The namespace, which must start with a forward slash, is set to ``/demo``\ , which means that topics are created in that namespace (\ ``/demo/my_topic``\ ), as opposed to globally (\ ``/my_topic``\ ). + +.. code-block:: + + ros2 run demo_nodes_cpp talker __ns:=/demo __node:=my_talker chatter:=my_topic + +Passing remapping arguments to specific nodes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If multiple nodes are being run within a single process (e.g. using `Composition `_\ ), remapping arguments can be passed to a specific node using its name as a prefix. +For example, the following will pass the remapping arguments to the specified nodes: + +.. code-block:: + + ros2 run composition manual_composition talker:__node:=my_talker listener:__node:=my_listener + +Logger configuration +-------------------- + +See `the logging page `. + +Parameters +---------- + +*Parameters are currently only supported for C++ nodes.* + +Setting parameters from the command-line is currently supported in the form of yaml files. + +`See here `__ for examples of the yaml file syntax. As an example, save the following as ``demo_params.yaml`` + +.. code-block:: yaml + + talker: + ros__parameters: + some_int: 42 + a_string: "Hello world" + some_lists: + some_integers: [1, 2, 3, 4] + some_doubles : [3.14, 2.718] + +Then run the following: + +.. code-block:: + + ros2 run demo_nodes_cpp talker __params:=demo_params.yaml + +Other nodes will be able to retrieve the parameter values, e.g.: + +.. code-block:: + + $ ros2 param list talker + a_string + some_int + some_lists.some_doubles + some_lists.some_integers diff --git a/OSX-Development-Setup.md b/OSX-Development-Setup.md deleted file mode 100644 index 9d38140ba7a..00000000000 --- a/OSX-Development-Setup.md +++ /dev/null @@ -1,213 +0,0 @@ -# Building ROS 2 on OS X - -## System requirements - -We support OS X 10.12.x. - -However, some new versions like 10.13.x and some older versions like 10.11.x and 10.10.x are known to work as well. - -## Install prerequisites - -You need the following things installed to build ROS 2: - -1. **Xcode** - * If you don't already have it installed, install Xcode and the Command Line Tools: - - ``` - xcode-select --install - ``` - -1. **brew** *(needed to install more stuff; you probably already have this)*: - * Follow installation instructions at http://brew.sh/ - * *Optional*: Check that `brew` is happy with your system configuration by running: - - ``` - brew doctor - ``` - - Fix any problems that it identifies. - -1. Use `brew` to install more stuff: - - brew install cmake cppcheck eigen pcre poco python3 tinyxml wget - - # install dependencies for Fast-RTPS if you are using it - brew install asio tinyxml2 - - brew install opencv - -1. Install rviz dependencies - - # install depepndencies for Rviz - brew install qt freetype assimp - - # Add the Qt directory to the CMAKE_PREFIX_PATH - export CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:/usr/local/opt/qt - -1. Use `python3 -m pip` (just `pip` may install Python3 or Python2) to install more stuff: - - python3 -m pip install argcomplete catkin_pkg colcon-common-extensions coverage empy flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes mock nose pep8 pydocstyle pyparsing setuptools vcstool - -1. *Optional*: if you want to build the ROS 1<->2 bridge, then you must also install ROS 1: - - * Start with the normal install instructions: http://wiki.ros.org/kinetic/Installation/OSX/Homebrew/Source - * When you get to the step where you call `rosinstall_generator` to get the source code, here's an alternate invocation that brings in just the minimum required to produce a useful bridge: - - rosinstall_generator catkin common_msgs roscpp rosmsg --rosdistro kinetic --deps --wet-only --tar > kinetic-ros2-bridge-deps.rosinstall - wstool init -j8 src kinetic-ros2-bridge-deps.rosinstall - - Otherwise, just follow the normal instructions, then source the resulting `install_isolated/setup.bash` before proceeding here to build ROS 2. - -## Disable System Integrity Protection (SIP) -OS X versions >=10.11 have System Integrity Protection enabled by default. -So that SIP doesn't prevent processes from inheriting dynamic linker environment variables, such as `DYLD_LIBRARY_PATH`, you'll need to disable it [following these instructions](https://developer.apple.com/library/content/documentation/Security/Conceptual/System_Integrity_Protection_Guide/ConfiguringSystemIntegrityProtection/ConfiguringSystemIntegrityProtection.html). - -## Get the ROS 2 code - -Create a workspace and clone all repos: - - mkdir -p ~/ros2_ws/src - cd ~/ros2_ws - wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos - vcs import src < ros2.repos - -> Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing `release-latest` in the url above with `master`. The `release-latest` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also [Maintaining a Source Checkout](Maintaining-a-Source-Checkout.md). - -## Optional: Install additional DDS vendors - -ROS 2.0 builds on top of DDS. -It is compatible with [multiple DDS or RTPS (the DDS wire protocol) vendors](DDS-and-ROS-middleware-implementations.md). -The repositories you downloaded for ROS 2.0 includes eProsima's Fast RTPS, which is the only bundled vendor. -If you would like to use one of the other vendors you will need to install their software separately before building. -The ROS 2.0 build will automatically build support for vendors that have been installed and sourced correctly. - -By default we include eProsima's FastRTPS in the workspace and it is the default middleware. -Detailed instructions for installing other DDS vendors are provided in the "Alternative DDS sources" section below. - -## Build the ROS 2 code - -**Note**: if you are trying to build the ROS 1 <-> ROS 2 bridge, follow instead these [modified instructions](https://github.com/ros2/ros1_bridge/blob/master/README.md#build-the-bridge-from-source). - -Run the `colcon` tool to build everything (more on using `colcon` in [this tutorial](Colcon-Tutorial.md)): - - cd ~/ros2_ws/ - colcon build --symlink-install - -## Try some examples - -In a clean new terminal, source the setup file (this will automatically set up the environment for any DDS vendors that support was built for) and then run a `talker`: - - . ~/ros2_ws/install/setup.bash - ros2 run demo_nodes_cpp talker - -In another terminal source the setup file and then run a `listener`: - - . ~/ros2_ws/install/setup.bash - ros2 run demo_nodes_cpp listener - -You should see the `talker` saying that it's `Publishing` messages and the `listener` saying `I heard` those messages. -Hooray! - -## Alternative DDS sources - -The demos will attempt to build against any detected DDS vendor. -The only bundled vendor is eProsima's Fast RTPS, which is included in the default set of sources for ROS 2.0. -If you would like to switch out the vendor below are the instructions. -When you run the build make sure that your chosen DDS vendor(s) are exposed in your environment. - -When multiple vendors are present, you can choose the used RMW implementation by setting the the environment variable `RMW_IMPLEMENTATION` to the package providing the RMW implementation. -See [Working with multiple RMW implementations](Working-with-multiple-RMW-implementations.md) for more details. - -### Adlink OpenSplice (6.7) - -To install OpenSplice, download the latest release from https://github.com/ADLINK-IST/opensplice/releases and unpack it. - -Source the `release.com` file provided to set up the environment before building your ROS 2 workspace, e.g.: - -``` -source /x86_64.darwin10_clang/release.com -``` - -### RTI Connext (5.3) - -To use RTI Connext you will need to have obtained a license from RTI. - -You can install the OS X package of Connext version 5.3 provided by RTI from their [downloads page](https://www.rti.com/downloads). - -You also need a Java runtime installed to run the RTI code generator, which you can get [here](https://support.apple.com/kb/DL1572?locale=en_US). - -After installing, run RTI launcher and point it to your license file. - -Source the setup file to set the `NDDSHOME` environment variable before building your workspace: - -``` -source /Applications/rti_connext_dds-5.3.1/resource/scripts/rtisetenv_x64Darwin16clang8.0.bash -``` - -You may need to increase shared memory resources following https://community.rti.com/kb/osx510. - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -## Troubleshooting - -### Segmentation Fault when using `pyenv` - -`pyenv` seems to default to building Python with `.a` files, but that causes issues with `rclpy`, so it's recommended to build Python with Frameworks enabled on macOS when using `pyenv`: - -https://github.com/pyenv/pyenv/wiki#how-to-build-cpython-with-framework-support-on-os-x - -### Library not loaded; image not found - -If you are seeing library loading issues at runtime (either running tests or running nodes), such as the following: - -``` -ImportError: dlopen(.../ros2_install/ros2-osx/lib/python3.7/site-packages/rclpy/_rclpy.cpython-37m-darwin.so, 2): Library not loaded: @rpath/librcl_interfaces__rosidl_typesupport_c.dylib - Referenced from: .../ros2_install/ros2-osx/lib/python3.7/site-packages/rclpy/_rclpy.cpython-37m-darwin.so - Reason: image not found -``` - -then you probably have System Integrity Protection enabled. -See "Disable System Integrity Protection (SIP)" above for how instructions on how to disable it. - -### Qt build errors e.g. `unknown type name 'Q_ENUM'` - -If you see build errors related to Qt, e.g.: -``` -In file included from /usr/local/opt/qt/lib/QtGui.framework/Headers/qguiapplication.h:46: -/usr/local/opt/qt/lib/QtGui.framework/Headers/qinputmethod.h:87:5: error: - unknown type name 'Q_ENUM' - Q_ENUM(Action) - ^ -``` - -you may be using qt4 instead of qt5: see https://github.com/ros2/ros2/issues/441 - -### Missing symbol when opencv (and therefore libjpeg, libtiff, and libpng) are installed with Homebrew - -If you have opencv installed you might get this: - -``` -dyld: Symbol not found: __cg_jpeg_resync_to_restart - Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO - Expected in: /usr/local/lib/libJPEG.dylib - in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO -/bin/sh: line 1: 25274 Trace/BPT trap: 5 /usr/local/bin/cmake -``` - -If so, to build you'll have to do this: - -``` -$ brew unlink libpng libtiff libjpeg -``` - -But this will break opencv, so you'll also need to update it to continue working: - -``` -$ sudo install_name_tool -change /usr/local/lib/libjpeg.8.dylib /usr/local/opt/jpeg/lib/libjpeg.8.dylib /usr/local/lib/libopencv_highgui.2.4.dylib -$ sudo install_name_tool -change /usr/local/lib/libpng16.16.dylib /usr/local/opt/libpng/lib/libpng16.16.dylib /usr/local/lib/libopencv_highgui.2.4.dylib -$ sudo install_name_tool -change /usr/local/lib/libtiff.5.dylib /usr/local/opt/libtiff/lib/libtiff.5.dylib /usr/local/lib/libopencv_highgui.2.4.dylib -$ sudo install_name_tool -change /usr/local/lib/libjpeg.8.dylib /usr/local/opt/jpeg/lib/libjpeg.8.dylib /usr/local/Cellar/libtiff/4.0.4/lib/libtiff.5.dylib -``` - -The first command is necessary to avoid things built against the system libjpeg (etc.) from getting the version in /usr/local/lib. -The others are updating things built by Homebrew so that they can find the version of libjpeg (etc.) without having them in /usr/local/lib. diff --git a/OSX-Development-Setup.rst b/OSX-Development-Setup.rst new file mode 100644 index 00000000000..0769a395c5e --- /dev/null +++ b/OSX-Development-Setup.rst @@ -0,0 +1,271 @@ + +Building ROS 2 on OS X +====================== + +System requirements +------------------- + +We support OS X 10.12.x. + +However, some new versions like 10.13.x and some older versions like 10.11.x and 10.10.x are known to work as well. + +Install prerequisites +--------------------- + +You need the following things installed to build ROS 2: + + +#. + **Xcode** + + + * + If you don't already have it installed, install Xcode and the Command Line Tools: + + .. code-block:: + + xcode-select --install + +#. + **brew** *(needed to install more stuff; you probably already have this)*\ : + + + * Follow installation instructions at http://brew.sh/ + * + *Optional*\ : Check that ``brew`` is happy with your system configuration by running: + + .. code-block:: + + brew doctor + + Fix any problems that it identifies. + +#. + Use ``brew`` to install more stuff: + + .. code-block:: + + brew install cmake cppcheck eigen pcre poco python3 tinyxml wget + + # install dependencies for Fast-RTPS if you are using it + brew install asio tinyxml2 + + brew install opencv + +#. + Install rviz dependencies + + .. code-block:: + + # install depepndencies for Rviz + brew install qt freetype assimp + + # Add the Qt directory to the CMAKE_PREFIX_PATH + export CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:/usr/local/opt/qt + +#. + Use ``python3 -m pip`` (just ``pip`` may install Python3 or Python2) to install more stuff: + + .. code-block:: + + python3 -m pip install argcomplete catkin_pkg colcon-common-extensions coverage empy flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes mock nose pep8 pydocstyle pyparsing setuptools vcstool + +#. + *Optional*\ : if you want to build the ROS 1<->2 bridge, then you must also install ROS 1: + + + * Start with the normal install instructions: http://wiki.ros.org/kinetic/Installation/OSX/Homebrew/Source + * + When you get to the step where you call ``rosinstall_generator`` to get the source code, here's an alternate invocation that brings in just the minimum required to produce a useful bridge: + + .. code-block:: + + rosinstall_generator catkin common_msgs roscpp rosmsg --rosdistro kinetic --deps --wet-only --tar > kinetic-ros2-bridge-deps.rosinstall + wstool init -j8 src kinetic-ros2-bridge-deps.rosinstall + + + Otherwise, just follow the normal instructions, then source the resulting ``install_isolated/setup.bash`` before proceeding here to build ROS 2. + +Disable System Integrity Protection (SIP) +----------------------------------------- + +OS X versions >=10.11 have System Integrity Protection enabled by default. +So that SIP doesn't prevent processes from inheriting dynamic linker environment variables, such as ``DYLD_LIBRARY_PATH``\ , you'll need to disable it `following these instructions `__. + +Get the ROS 2 code +------------------ + +Create a workspace and clone all repos: + +.. code-block:: + + mkdir -p ~/ros2_ws/src + cd ~/ros2_ws + wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos + vcs import src < ros2.repos + + +.. + + Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing ``release-latest`` in the url above with ``master``. The ``release-latest`` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also `Maintaining a Source Checkout `. + + +Optional: Install additional DDS vendors +---------------------------------------- + +ROS 2.0 builds on top of DDS. +It is compatible with `multiple DDS or RTPS (the DDS wire protocol) vendors `. +The repositories you downloaded for ROS 2.0 includes eProsima's Fast RTPS, which is the only bundled vendor. +If you would like to use one of the other vendors you will need to install their software separately before building. +The ROS 2.0 build will automatically build support for vendors that have been installed and sourced correctly. + +By default we include eProsima's FastRTPS in the workspace and it is the default middleware. +Detailed instructions for installing other DDS vendors are provided in the "Alternative DDS sources" section below. + +Build the ROS 2 code +-------------------- + +**Note**\ : if you are trying to build the ROS 1 <-> ROS 2 bridge, follow instead these `modified instructions `__. + +Run the ``colcon`` tool to build everything (more on using ``colcon`` in `this tutorial `\ ): + +.. code-block:: + + cd ~/ros2_ws/ + colcon build --symlink-install + + +Try some examples +----------------- + +In a clean new terminal, source the setup file (this will automatically set up the environment for any DDS vendors that support was built for) and then run a ``talker``\ : + +.. code-block:: + + . ~/ros2_ws/install/setup.bash + ros2 run demo_nodes_cpp talker + + +In another terminal source the setup file and then run a ``listener``\ : + +.. code-block:: + + . ~/ros2_ws/install/setup.bash + ros2 run demo_nodes_cpp listener + + +You should see the ``talker`` saying that it's ``Publishing`` messages and the ``listener`` saying ``I heard`` those messages. +Hooray! + +Alternative DDS sources +----------------------- + +The demos will attempt to build against any detected DDS vendor. +The only bundled vendor is eProsima's Fast RTPS, which is included in the default set of sources for ROS 2.0. +If you would like to switch out the vendor below are the instructions. +When you run the build make sure that your chosen DDS vendor(s) are exposed in your environment. + +When multiple vendors are present, you can choose the used RMW implementation by setting the the environment variable ``RMW_IMPLEMENTATION`` to the package providing the RMW implementation. +See `Working with multiple RMW implementations ` for more details. + +Adlink OpenSplice (6.7) +^^^^^^^^^^^^^^^^^^^^^^^ + +To install OpenSplice, download the latest release from https://github.com/ADLINK-IST/opensplice/releases and unpack it. + +Source the ``release.com`` file provided to set up the environment before building your ROS 2 workspace, e.g.: + +.. code-block:: + + source /x86_64.darwin10_clang/release.com + +RTI Connext (5.3) +^^^^^^^^^^^^^^^^^ + +To use RTI Connext you will need to have obtained a license from RTI. + +You can install the OS X package of Connext version 5.3 provided by RTI from their `downloads page `__. + +You also need a Java runtime installed to run the RTI code generator, which you can get `here `__. + +After installing, run RTI launcher and point it to your license file. + +Source the setup file to set the ``NDDSHOME`` environment variable before building your workspace: + +.. code-block:: + + source /Applications/rti_connext_dds-5.3.1/resource/scripts/rtisetenv_x64Darwin16clang8.0.bash + +You may need to increase shared memory resources following https://community.rti.com/kb/osx510. + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +Troubleshooting +--------------- + +Segmentation Fault when using ``pyenv`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``pyenv`` seems to default to building Python with ``.a`` files, but that causes issues with ``rclpy``\ , so it's recommended to build Python with Frameworks enabled on macOS when using ``pyenv``\ : + +https://github.com/pyenv/pyenv/wiki#how-to-build-cpython-with-framework-support-on-os-x + +Library not loaded; image not found +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you are seeing library loading issues at runtime (either running tests or running nodes), such as the following: + +.. code-block:: + + ImportError: dlopen(.../ros2_install/ros2-osx/lib/python3.7/site-packages/rclpy/_rclpy.cpython-37m-darwin.so, 2): Library not loaded: @rpath/librcl_interfaces__rosidl_typesupport_c.dylib + Referenced from: .../ros2_install/ros2-osx/lib/python3.7/site-packages/rclpy/_rclpy.cpython-37m-darwin.so + Reason: image not found + +then you probably have System Integrity Protection enabled. +See "Disable System Integrity Protection (SIP)" above for how instructions on how to disable it. + +Qt build errors e.g. ``unknown type name 'Q_ENUM'`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you see build errors related to Qt, e.g.: + +.. code-block:: + + In file included from /usr/local/opt/qt/lib/QtGui.framework/Headers/qguiapplication.h:46: + /usr/local/opt/qt/lib/QtGui.framework/Headers/qinputmethod.h:87:5: error: + unknown type name 'Q_ENUM' + Q_ENUM(Action) + ^ + +you may be using qt4 instead of qt5: see https://github.com/ros2/ros2/issues/441 + +Missing symbol when opencv (and therefore libjpeg, libtiff, and libpng) are installed with Homebrew +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you have opencv installed you might get this: + +.. code-block:: + + dyld: Symbol not found: __cg_jpeg_resync_to_restart + Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO + Expected in: /usr/local/lib/libJPEG.dylib + in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO + /bin/sh: line 1: 25274 Trace/BPT trap: 5 /usr/local/bin/cmake + +If so, to build you'll have to do this: + +.. code-block:: + + $ brew unlink libpng libtiff libjpeg + +But this will break opencv, so you'll also need to update it to continue working: + +.. code-block:: + + $ sudo install_name_tool -change /usr/local/lib/libjpeg.8.dylib /usr/local/opt/jpeg/lib/libjpeg.8.dylib /usr/local/lib/libopencv_highgui.2.4.dylib + $ sudo install_name_tool -change /usr/local/lib/libpng16.16.dylib /usr/local/opt/libpng/lib/libpng16.16.dylib /usr/local/lib/libopencv_highgui.2.4.dylib + $ sudo install_name_tool -change /usr/local/lib/libtiff.5.dylib /usr/local/opt/libtiff/lib/libtiff.5.dylib /usr/local/lib/libopencv_highgui.2.4.dylib + $ sudo install_name_tool -change /usr/local/lib/libjpeg.8.dylib /usr/local/opt/jpeg/lib/libjpeg.8.dylib /usr/local/Cellar/libtiff/4.0.4/lib/libtiff.5.dylib + +The first command is necessary to avoid things built against the system libjpeg (etc.) from getting the version in /usr/local/lib. +The others are updating things built by Homebrew so that they can find the version of libjpeg (etc.) without having them in /usr/local/lib. diff --git a/OSX-Install-Binary.md b/OSX-Install-Binary.md deleted file mode 100644 index 403f6931c67..00000000000 --- a/OSX-Install-Binary.md +++ /dev/null @@ -1,125 +0,0 @@ -# Installing ROS 2 on OS X - -This page explains how to install ROS 2 on OS X from a pre-built binary package. - -## System requirements - -We support OS X El Capitan and Sierra (10.11.x and 10.12.x). - -## Installing prerequisites - -You need the following things installed before installing ROS 2. - -- **brew** *(needed to install more stuff; you probably already have this)*: - - Follow installation instructions at http://brew.sh/ - - *Optional*: Check that `brew` is happy with your system configuration by running: - - brew doctor - - Fix any problems that it identifies. - -- Use `brew` to install more stuff: - - brew install python3 - - # install asio and tinyxml2 for Fast-RTPS - brew install asio tinyxml2 - - # install dependencies for robot state publisher - brew install tinyxml eigen pcre poco - - # OpenCV isn't a dependency of ROS 2, but it is used by some demos. - brew install opencv - - # install OpenSSL for DDS-Security - brew install openssl - - # install Qt for RViz - brew install qt freetype assimp - -- Install additional runtime dependencies for command-line tools: - - python3 -m pip install catkin_pkg empy pyparsing pyyaml setuptools argcomplete - - -## Disable System Integrity Protection (SIP) - -OS X versions >=10.11 have System Integrity Protection enabled by default. -So that SIP doesn't prevent processes from inheriting dynamic linker environment variables, such as `DYLD_LIBRARY_PATH`, you'll need to disable it [following these instructions](https://developer.apple.com/library/content/documentation/Security/Conceptual/System_Integrity_Protection_Guide/ConfiguringSystemIntegrityProtection/ConfiguringSystemIntegrityProtection.html). - -## Downloading ROS 2 - -- Go the releases page: https://github.com/ros2/ros2/releases -- Download the latest package for OS X; let's assume that it ends up at `~/Downloads/ros2-package-osx-x86_64.tar.bz2`. - - Note: there may be more than one binary download option which might cause the file name to differ. -- Unpack it: - - mkdir -p ~/ros2_install - cd ~/ros2_install - tar xf ~/Downloads/ros2-package-osx-x86_64.tar.bz2 - -## Install additional DDS implementations (optional) - -ROS 2 builds on top of DDS. -It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. - -_For ROS 2 Bouncy and newer:_ - -The package you downloaded has been built with _optional_ support for three vendors. -Run-time support for eProsima's Fast RTPS is included bundled by default. -If you would like to use one of the other vendors you will need to install their software separately. - -_For ROS 2 Ardent and older:_ - -If you downloaded a package that includes support for OpenSplice, you must install OpenSplice as detailed below. - -### To enable OpenSplice support: -Download the latest release from https://github.com/ADLINK-IST/opensplice/releases and unpack it. -For ROS 2 releases up to and including Ardent, do not do anything else at this point. -For ROS 2 releases later than Ardent, set the `OSPL_HOME` environment variable to the unpacked directory that contains the `release.com` script. - -### To enable Connext support: -To use RTI Connext you will need to have obtained a license from RTI. - -You can install the OS X package of Connext version 5.3.1 provided by RTI from their [downloads page](https://www.rti.com/downloads). - -After installing, run RTI launcher and point it to your license file. - -Set the `NDDSHOME` environment variable: - -``` -export NDDSHOME=/Applications/rti_connext_dds-5.3.1/ -``` - -You may need to increase shared memory resources following https://community.rti.com/kb/osx510. - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -## Set up the ROS 2 environment - -Source the ROS 2 setup file: - - . ~/ros2_install/ros2-osx/setup.bash - -For ROS 2 releases up to and including Ardent, if you downloaded a release with OpenSplice support you must additionally source the OpenSplice setup file manually (this is done automatically for ROS 2 releases later than Ardent). -Only do this **after** you have sourced the ROS 2 one: - - . /x86_64.darwin10_clang/release.com - - -## Try some examples - -In one terminal, set up the ROS 2 environment as described above and then run a `talker`: - - ros2 run demo_nodes_cpp talker - -In another terminal, set up the ROS 2 environment and then run a `listener`: - - ros2 run demo_nodes_cpp listener - -You should see the `talker` saying that it's `Publishing` messages and the `listener` saying `I heard` those messages. -Hooray! - -If you have installed support for an optional vendor, see [this page](Working-with-multiple-RMW-implementations.md) for details on how to use that vendor. - -If you run into issues, see [the troubleshooting section](OSX-Development-Setup.md#troubleshooting) on the source installation page. diff --git a/OSX-Install-Binary.rst b/OSX-Install-Binary.rst new file mode 100644 index 00000000000..af75bb6e715 --- /dev/null +++ b/OSX-Install-Binary.rst @@ -0,0 +1,169 @@ + +Installing ROS 2 on OS X +======================== + +This page explains how to install ROS 2 on OS X from a pre-built binary package. + +System requirements +------------------- + +We support OS X El Capitan and Sierra (10.11.x and 10.12.x). + +Installing prerequisites +------------------------ + +You need the following things installed before installing ROS 2. + + +* + **brew** *(needed to install more stuff; you probably already have this)*\ : + + + * Follow installation instructions at http://brew.sh/ + * + *Optional*\ : Check that ``brew`` is happy with your system configuration by running: + + .. code-block:: + + brew doctor + + + Fix any problems that it identifies. + +* + Use ``brew`` to install more stuff: + + .. code-block:: + + brew install python3 + + # install asio and tinyxml2 for Fast-RTPS + brew install asio tinyxml2 + + # install dependencies for robot state publisher + brew install tinyxml eigen pcre poco + + # OpenCV isn't a dependency of ROS 2, but it is used by some demos. + brew install opencv + + # install OpenSSL for DDS-Security + brew install openssl + + # install Qt for RViz + brew install qt freetype assimp + +* + Install additional runtime dependencies for command-line tools: + + .. code-block:: + + python3 -m pip install catkin_pkg empy pyparsing pyyaml setuptools argcomplete + +Disable System Integrity Protection (SIP) +----------------------------------------- + +OS X versions >=10.11 have System Integrity Protection enabled by default. +So that SIP doesn't prevent processes from inheriting dynamic linker environment variables, such as ``DYLD_LIBRARY_PATH``\ , you'll need to disable it `following these instructions `__. + +Downloading ROS 2 +----------------- + + +* Go the releases page: https://github.com/ros2/ros2/releases +* Download the latest package for OS X; let's assume that it ends up at ``~/Downloads/ros2-package-osx-x86_64.tar.bz2``. + + * Note: there may be more than one binary download option which might cause the file name to differ. + +* + Unpack it: + + .. code-block:: + + mkdir -p ~/ros2_install + cd ~/ros2_install + tar xf ~/Downloads/ros2-package-osx-x86_64.tar.bz2 + +Install additional DDS implementations (optional) +------------------------------------------------- + +ROS 2 builds on top of DDS. +It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. + +*For ROS 2 Bouncy and newer:* + +The package you downloaded has been built with *optional* support for three vendors. +Run-time support for eProsima's Fast RTPS is included bundled by default. +If you would like to use one of the other vendors you will need to install their software separately. + +*For ROS 2 Ardent and older:* + +If you downloaded a package that includes support for OpenSplice, you must install OpenSplice as detailed below. + +To enable OpenSplice support: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Download the latest release from https://github.com/ADLINK-IST/opensplice/releases and unpack it. +For ROS 2 releases up to and including Ardent, do not do anything else at this point. +For ROS 2 releases later than Ardent, set the ``OSPL_HOME`` environment variable to the unpacked directory that contains the ``release.com`` script. + +To enable Connext support: +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To use RTI Connext you will need to have obtained a license from RTI. + +You can install the OS X package of Connext version 5.3.1 provided by RTI from their `downloads page `__. + +After installing, run RTI launcher and point it to your license file. + +Set the ``NDDSHOME`` environment variable: + +.. code-block:: + + export NDDSHOME=/Applications/rti_connext_dds-5.3.1/ + +You may need to increase shared memory resources following https://community.rti.com/kb/osx510. + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +Set up the ROS 2 environment +---------------------------- + +Source the ROS 2 setup file: + +.. code-block:: + + . ~/ros2_install/ros2-osx/setup.bash + + +For ROS 2 releases up to and including Ardent, if you downloaded a release with OpenSplice support you must additionally source the OpenSplice setup file manually (this is done automatically for ROS 2 releases later than Ardent). +Only do this **after** you have sourced the ROS 2 one: + +.. code-block:: + + . /x86_64.darwin10_clang/release.com + + + +Try some examples +----------------- + +In one terminal, set up the ROS 2 environment as described above and then run a ``talker``\ : + +.. code-block:: + + ros2 run demo_nodes_cpp talker + + +In another terminal, set up the ROS 2 environment and then run a ``listener``\ : + +.. code-block:: + + ros2 run demo_nodes_cpp listener + + +You should see the ``talker`` saying that it's ``Publishing`` messages and the ``listener`` saying ``I heard`` those messages. +Hooray! + +If you have installed support for an optional vendor, see `this page ` for details on how to use that vendor. + +If you run into issues, see `the troubleshooting section ` on the source installation page. diff --git a/Overview-of-ROS-2-concepts.md b/Overview-of-ROS-2-concepts.rst similarity index 63% rename from Overview-of-ROS-2-concepts.md rename to Overview-of-ROS-2-concepts.rst index f9327474ad7..3181b3705f2 100644 --- a/Overview-of-ROS-2-concepts.md +++ b/Overview-of-ROS-2-concepts.rst @@ -1,15 +1,21 @@ + ROS is a middleware based on an anonymous publish/subscribe mechanism that allows for message passing between different ROS processes. At the heart of any ROS 2 system is the ROS graph. The ROS graph refers to the network of nodes in a ROS system and the connections between them by which they communicate. -## Quick Overview of Graph Concepts -- Nodes: A node is an entity that uses ROS to communicate with other nodes. -- Messages: ROS data type used when subscribing or publishing to a topic. -- Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages. -- Discovery: The automatic process through which nodes determine how to talk to each other. +Quick Overview of Graph Concepts +-------------------------------- + + +* Nodes: A node is an entity that uses ROS to communicate with other nodes. +* Messages: ROS data type used when subscribing or publishing to a topic. +* Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages. +* Discovery: The automatic process through which nodes determine how to talk to each other. + +Nodes +----- -## Nodes A node is a participant in the ROS graph. ROS nodes use a ROS client library to communicate with other nodes. Nodes can publish or subscribe to a Topic. @@ -19,39 +25,49 @@ Connections between nodes are established through a distributed discovery proces Nodes may be located in the same process, in different processes, or on different machines. These concepts will be described in more detail in the sections that follow. -## Client Libraries +Client Libraries +---------------- + ROS client libraries allow nodes written in different programming languages to communicate. There is a core ROS client library (RCL) that implements common functionality needed for the ROS APIs of different languages. This makes it so that language-specific client libraries are easier to write and that they have more consistent behavior. The following client libraries are maintained by the ROS 2 team: -- rclcpp = C++ client library -- rclpy = Python client library + + +* rclcpp = C++ client library +* rclpy = Python client library Additionally, other client libraries have been developed by the ROS community. -See the [ROS 2 Client Libraries](ROS-2-Client-Libraries.md) article for more details. +See the `ROS 2 Client Libraries ` article for more details. + +Discovery +--------- -## Discovery Discovery of nodes happens automatically through the underlying middleware of ROS 2. It can be summarized as follows: -1. When a node is started, it advertises its presence to other nodes on the network with the same ROS domain (set with the ROS_DOMAIN_ID environment variable). -Nodes respond to this advertisement with information about themselves so that the appropriate connections can be made and the nodes can communicate. -2. Nodes periodically advertise their presence so that connections can be made with new-found entities, even after the initial discovery period. -3. Nodes advertise to other nodes when they go offline. -Nodes will only establish connections with other nodes if they have compatible [Quality of Service](Quality-of-Service.md) settings. +#. When a node is started, it advertises its presence to other nodes on the network with the same ROS domain (set with the ROS_DOMAIN_ID environment variable). + Nodes respond to this advertisement with information about themselves so that the appropriate connections can be made and the nodes can communicate. +#. Nodes periodically advertise their presence so that connections can be made with new-found entities, even after the initial discovery period. +#. Nodes advertise to other nodes when they go offline. + +Nodes will only establish connections with other nodes if they have compatible `Quality of Service ` settings. +Example: talker-listener +------------------------ -## Example: talker-listener In one terminal, start a node (written in C++) that will publish messages on a topic. -``` -ros2 run demo_nodes_cpp talker -``` + +.. code-block:: + + ros2 run demo_nodes_cpp talker In another terminal, start a second node (written in Python) that will subscribe to messages on the same topic. -``` -ros2 run demo_nodes_py listener -``` -You should see that these nodes discover each other automatically, and begin to exchange messages. \ No newline at end of file +.. code-block:: + + ros2 run demo_nodes_py listener + +You should see that these nodes discover each other automatically, and begin to exchange messages. diff --git a/Python-Programming.md b/Python-Programming.md deleted file mode 100644 index 3da249b4f3e..00000000000 --- a/Python-Programming.md +++ /dev/null @@ -1,33 +0,0 @@ -## Background - -One of the most popular features of ROS 1 is the ability of writing robot applications in a variety of languages. Starting with Alpha 4, ROS 2 provides a Python API that can be used for communicating with other nodes written in different languages. - -## Install - -The `rclpy` module enables developers to use the ROS 2 API from Python. As of Alpha 4, `rclpy` is still under development and its API might change, but for now the basics (publishers and subscriptions) can be accessed from Python. - -`rclpy` is part of the standard ROS 2 distribution, so it'll be installed alongside the rest of the ROS 2 packages. - -## Run the examples - -The two classic ROS 2 examples of a "talker" and a "listener" have been implemented in Python using `rclpy`. The source code is available [here](https://github.com/ros2/demos/tree/master/demo_nodes_py). - -Open two terminals, source the appropriate `setup.*`/`local_setup.*` file in the terminals, and run `ros2 run demo_nodes_py talker` in one and `ros2 run demo_nodes_py listener` in the other. - -Once executed you should see the following on the terminal running the listener: - -``` -I heard: [Hello World: 1] -I heard: [Hello World: 2] -I heard: [Hello World: 3] -I heard: [Hello World: 4] -I heard: [Hello World: 5] -I heard: [Hello World: 6] -I heard: [Hello World: 7] -I heard: [Hello World: 8] -I heard: [Hello World: 9] -I heard: [Hello World: 10] -``` - -## Communication with nodes using different ROS client libraries -Since `rclpy` uses the underlying ROS 2 infrastructure, Python programs that use `rclpy` can also communicate with applications written in C++, even if they use a different DDS vendor and are running on a different operating system. \ No newline at end of file diff --git a/Python-Programming.rst b/Python-Programming.rst new file mode 100644 index 00000000000..b5d699c0cce --- /dev/null +++ b/Python-Programming.rst @@ -0,0 +1,39 @@ + +Background +---------- + +One of the most popular features of ROS 1 is the ability of writing robot applications in a variety of languages. Starting with Alpha 4, ROS 2 provides a Python API that can be used for communicating with other nodes written in different languages. + +Install +------- + +The ``rclpy`` module enables developers to use the ROS 2 API from Python. As of Alpha 4, ``rclpy`` is still under development and its API might change, but for now the basics (publishers and subscriptions) can be accessed from Python. + +``rclpy`` is part of the standard ROS 2 distribution, so it'll be installed alongside the rest of the ROS 2 packages. + +Run the examples +---------------- + +The two classic ROS 2 examples of a "talker" and a "listener" have been implemented in Python using ``rclpy``. The source code is available `here `__. + +Open two terminals, source the appropriate ``setup.*``\ /\ ``local_setup.*`` file in the terminals, and run ``ros2 run demo_nodes_py talker`` in one and ``ros2 run demo_nodes_py listener`` in the other. + +Once executed you should see the following on the terminal running the listener: + +.. code-block:: + + I heard: [Hello World: 1] + I heard: [Hello World: 2] + I heard: [Hello World: 3] + I heard: [Hello World: 4] + I heard: [Hello World: 5] + I heard: [Hello World: 6] + I heard: [Hello World: 7] + I heard: [Hello World: 8] + I heard: [Hello World: 9] + I heard: [Hello World: 10] + +Communication with nodes using different ROS client libraries +------------------------------------------------------------- + +Since ``rclpy`` uses the underlying ROS 2 infrastructure, Python programs that use ``rclpy`` can also communicate with applications written in C++, even if they use a different DDS vendor and are running on a different operating system. diff --git a/Quality-Guide.md b/Quality-Guide.md deleted file mode 100644 index 5f8f7a76f3c..00000000000 --- a/Quality-Guide.md +++ /dev/null @@ -1,160 +0,0 @@ -This section tries to give guidance about how to improve the software quality of ROS2 packages. The guide uses a pattern language based approach to improve the readers experience ("read little, understand fast, understand much, apply easily"). - -**What this sections is about:** - -- ROS2 core, application and ecosystem packages. -- ROS2 core client libraries C++ and Python (right now: mainly C++) -- Design and implementation considerations to improve quality attributes like "Reliability", "Security", "Maintainability", "Determinism", etc. which relate to non-functional requirements (right now: mainly "Reliability"). - -**What this section is not about:** - -- Design and implementation considerations which go beyond a single ROS2 package and a single ROS2 node (means no integration considerations w.r.t. ROS2 graphs, etc.). -- Organizational considerations to improve software quality (an organizations structure and processes, etc.). -- Infrastructural considerations which go beyond a single repository (overall continuous integration infrastructure, etc.) - -**Relation to other sections:** - -- The [Design Guide](Design-Guide.md) summarizes design patterns for ROS2 packages. As quality is highly impacted by design it is a good idea to have a look into there before. -- The [Developer Guide](Developer-Guide.md) explains what to consider when contributing to ROS2 packages w.r.t. to contribution workflow (organizational), coding conventions, documentation considerations, etc. All these consideration may have an impact on single or several quality attributes. - -## Patterns - -* Static code analysis - * Static code analysis using a single tool - * Static code analysis using multiple tools complementary - * Static code analysis as part of the ament package build -* Dynamic code analysis -* ROS2 library test - * (referencing of generic unit test patterns like from [xUnitPatterns](http://xunitpatterns.com/Book%20Outline%20Diagrams.html) with references to C++ gtest+gmock/Python unittest implementations) - * (ROS2 specific unit test use cases) - * Property based test (C++ [RapidCheck](https://github.com/emil-e/rapidcheck) / Python [hypothesis](https://github.com/HypothesisWorks/hypothesis-python)) - * Code coverage analysis -* ROS2 node unit test - * (generic use cases of `launch` based tests) - -## Static code analysis as part of the ament package build - -**Context**: - -* You have developed your C++ production code. -* You have created a ROS2 package with build support with `ament`. - -**Problem**: - -* Library level static code analysis is not run as part of the package build procedure. -* Library level static code analysis needs to be executed manually. -* Risk of forgetting to execute library level static code analysis before building - a new package version. - -**Solution**: - -* Use the integration capabilities of `ament` to execute static code analysis as - part of the package build procedure. - -**Implementation**: - -* Insert into the packages `CMakeLists.txt` file. - -``` -... -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - ament_lint_auto_find_test_dependencies() - ... -endif() -... -``` - -* Insert the `ament_lint` test dependencies into the packages `package.xml` file. - -``` -... - - ... - ament_lint_auto - ament_lint_common - ... - -``` - -**Examples**: - -* `rclcpp`: - * [rclcpp/rclcpp/CMakeLists.txt](https://github.com/ros2/rclcpp/blob/master/rclcpp/CMakeLists.txt) - * [rclcpp/rclcpp/package.xml](https://github.com/ros2/rclcpp/blob/master/rclcpp/package.xml) -* `rclcpp_lifecycle`: - * [rclcpp/rclcpp_lifecycle/CMakeLists.txt](https://github.com/ros2/rclcpp/blob/master/rclcpp_lifecycle/CMakeLists.txt) - * [rclcpp/rclcpp_lifecycle/package.xml](https://github.com/ros2/rclcpp/blob/master/rclcpp_lifecycle/package.xml) - -**Resulting context**: - -* The static code analysis tools supported by `ament` are run as part of the package build. -* Static code analysis tools not supported by `ament` need to be executed separately. - -## Dynamic analysis (data races & deadlocks) - -**Context:** - -* You are developing/debugging your multithreaded C++ production code. -* You use pthreads or C++11 threading + llvm libc++ (in case of ThreadSanatizer). -* You do not use Libc/libstdc++ static linking (in case of ThreadSanatizer). -* You do not build non-position-independent executables (in case of ThreadSanatizer). - -**Problem:** - -* Data races and deadlocks can lead to critical bugs. -* Data races and deadlocks cannot be detected using static analysis (reason: limitation of static analysis). -* Data races and deadlocks must not show up during development debugging / testing (reason: usually not all possible control paths through production code exercised). - -**Solution:** - -* Use a dynamic analysis tool which focuses on finding data races and deadlocks (here clang ThreadSanatizer). - -**Implementation:** - -* Compile and link the production code with clang using the option `-fsanitize=thread` (this instruments the production code). -* In case different production code shall be executed during anaylsis consider conditional compilation e.g. [ThreadSanatizers _has_feature(thread_sanitizer)](https://clang.llvm.org/docs/ThreadSanitizer.html#has-feature-thread-sanitizer). -* In case some code shall not be instrumented consider [ThreadSanatizers _/_attribute_/_((no_sanitize("thread")))](https://clang.llvm.org/docs/ThreadSanitizer.html#attribute-no-sanitize-thread). -* In case some files shall not be instrumented consider file or function level exclusion [ThreadSanatizers blacklisting](https://clang.llvm.org/docs/ThreadSanitizer.html#blacklist), more specific: [ThreadSanatizers Sanitizer Special Case List](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) or with [ThreadSanatizers no_sanitize("thread")](https://clang.llvm.org/docs/ThreadSanitizer.html#blacklist) and use the option `--fsanitize-blacklist`. - -**Resulting context:** - -* Higher chance to find data races and deadlocks in production code before deploying it. -* Analysis result may lack reliability, tool in beta phase stage (in case of ThreadSanatizer). -* Overhead due to production code instrumentation (maintenance of separate branches for instrumented/not instrumented production code, etc.). -* Instrumented code needs more memory per thread (in case of ThreadSanatizer). -* Instrumented code maps a lot virtual address space (in case of ThreadSanatizer). - -## Code coverage analysis - -**Context** - -You have written tests for the library level production code of a ROS2 package (usually refered to as "unit tests"). - -**Problem** - -You do not know how much of the production code is exercised during the execution of the tests. - -**Solution** - -Select and use a code coverage analysis tool to determine the code coverage. - -**Forces** - -* Is it possible to integrate the tool with your source code editor? -* If not web service based: Is it possible to integrate the tool with your continuous integration infrastructure? -* What type(s) of coverage measurements (e.g. statement coverage) does the tool support? - -**Example** - -* C++ - * [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) + [lcov](http://ltp.sourceforge.net/coverage/lcov.php) - * [coveralls.io](https://coveralls.io) -* Python - * [coveralls.io](https://coveralls.io) - -**Resulting context** - -* You know how much of your production code was exercised during the execution of the unit tests. -* You have a more or less immediate feedback about the code coverage (editor integration / web service front end). -* You do not know anything about the quality of your tests. (The only way to figure that out is some kind of review). diff --git a/Quality-Guide.rst b/Quality-Guide.rst new file mode 100644 index 00000000000..8f333cce890 --- /dev/null +++ b/Quality-Guide.rst @@ -0,0 +1,195 @@ + +This section tries to give guidance about how to improve the software quality of ROS2 packages. The guide uses a pattern language based approach to improve the readers experience ("read little, understand fast, understand much, apply easily"). + +**What this sections is about:** + + +* ROS2 core, application and ecosystem packages. +* ROS2 core client libraries C++ and Python (right now: mainly C++) +* Design and implementation considerations to improve quality attributes like "Reliability", "Security", "Maintainability", "Determinism", etc. which relate to non-functional requirements (right now: mainly "Reliability"). + +**What this section is not about:** + + +* Design and implementation considerations which go beyond a single ROS2 package and a single ROS2 node (means no integration considerations w.r.t. ROS2 graphs, etc.). +* Organizational considerations to improve software quality (an organizations structure and processes, etc.). +* Infrastructural considerations which go beyond a single repository (overall continuous integration infrastructure, etc.) + +**Relation to other sections:** + + +* The `Design Guide ` summarizes design patterns for ROS2 packages. As quality is highly impacted by design it is a good idea to have a look into there before. +* The `Developer Guide ` explains what to consider when contributing to ROS2 packages w.r.t. to contribution workflow (organizational), coding conventions, documentation considerations, etc. All these consideration may have an impact on single or several quality attributes. + +Patterns +-------- + + +* Static code analysis + + * Static code analysis using a single tool + * Static code analysis using multiple tools complementary + * Static code analysis as part of the ament package build + +* Dynamic code analysis +* ROS2 library test + + * (referencing of generic unit test patterns like from `xUnitPatterns `__ with references to C++ gtest+gmock/Python unittest implementations) + * (ROS2 specific unit test use cases) + * Property based test (C++ `RapidCheck `__ / Python `hypothesis `__\ ) + * Code coverage analysis + +* ROS2 node unit test + + * (generic use cases of ``launch`` based tests) + +Static code analysis as part of the ament package build +------------------------------------------------------- + +**Context**\ : + + +* You have developed your C++ production code. +* You have created a ROS2 package with build support with ``ament``. + +**Problem**\ : + + +* Library level static code analysis is not run as part of the package build procedure. +* Library level static code analysis needs to be executed manually. +* Risk of forgetting to execute library level static code analysis before building + a new package version. + +**Solution**\ : + + +* Use the integration capabilities of ``ament`` to execute static code analysis as + part of the package build procedure. + +**Implementation**\ : + + +* Insert into the packages ``CMakeLists.txt`` file. + +.. code-block:: + + ... + if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + ament_lint_auto_find_test_dependencies() + ... + endif() + ... + + +* Insert the ``ament_lint`` test dependencies into the packages ``package.xml`` file. + +.. code-block:: + + ... + + ... + ament_lint_auto + ament_lint_common + ... + + +**Examples**\ : + + +* ``rclcpp``\ : + + * `rclcpp/rclcpp/CMakeLists.txt `__ + * `rclcpp/rclcpp/package.xml `__ + +* ``rclcpp_lifecycle``\ : + + * `rclcpp/rclcpp_lifecycle/CMakeLists.txt `__ + * `rclcpp/rclcpp_lifecycle/package.xml `__ + +**Resulting context**\ : + + +* The static code analysis tools supported by ``ament`` are run as part of the package build. +* Static code analysis tools not supported by ``ament`` need to be executed separately. + +Dynamic analysis (data races & deadlocks) +----------------------------------------- + +**Context:** + + +* You are developing/debugging your multithreaded C++ production code. +* You use pthreads or C++11 threading + llvm libc++ (in case of ThreadSanatizer). +* You do not use Libc/libstdc++ static linking (in case of ThreadSanatizer). +* You do not build non-position-independent executables (in case of ThreadSanatizer). + +**Problem:** + + +* Data races and deadlocks can lead to critical bugs. +* Data races and deadlocks cannot be detected using static analysis (reason: limitation of static analysis). +* Data races and deadlocks must not show up during development debugging / testing (reason: usually not all possible control paths through production code exercised). + +**Solution:** + + +* Use a dynamic analysis tool which focuses on finding data races and deadlocks (here clang ThreadSanatizer). + +**Implementation:** + + +* Compile and link the production code with clang using the option ``-fsanitize=thread`` (this instruments the production code). +* In case different production code shall be executed during anaylsis consider conditional compilation e.g. `ThreadSanatizers _has_feature(thread_sanitizer) `__. +* In case some code shall not be instrumented consider `ThreadSanatizers _/\ *attribute*\ /_((no_sanitize("thread"))) `__. +* In case some files shall not be instrumented consider file or function level exclusion `ThreadSanatizers blacklisting `__\ , more specific: `ThreadSanatizers Sanitizer Special Case List `__ or with `ThreadSanatizers no_sanitize("thread") `__ and use the option ``--fsanitize-blacklist``. + +**Resulting context:** + + +* Higher chance to find data races and deadlocks in production code before deploying it. +* Analysis result may lack reliability, tool in beta phase stage (in case of ThreadSanatizer). +* Overhead due to production code instrumentation (maintenance of separate branches for instrumented/not instrumented production code, etc.). +* Instrumented code needs more memory per thread (in case of ThreadSanatizer). +* Instrumented code maps a lot virtual address space (in case of ThreadSanatizer). + +Code coverage analysis +---------------------- + +**Context** + +You have written tests for the library level production code of a ROS2 package (usually refered to as "unit tests"). + +**Problem** + +You do not know how much of the production code is exercised during the execution of the tests. + +**Solution** + +Select and use a code coverage analysis tool to determine the code coverage. + +**Forces** + + +* Is it possible to integrate the tool with your source code editor? +* If not web service based: Is it possible to integrate the tool with your continuous integration infrastructure? +* What type(s) of coverage measurements (e.g. statement coverage) does the tool support? + +**Example** + + +* C++ + + * `gcov `__ + `lcov `__ + * `coveralls.io `__ + +* Python + + * `coveralls.io `__ + +**Resulting context** + + +* You know how much of your production code was exercised during the execution of the unit tests. +* You have a more or less immediate feedback about the code coverage (editor integration / web service front end). +* You do not know anything about the quality of your tests. (The only way to figure that out is some kind of review). diff --git a/Quality-of-Service.md b/Quality-of-Service.md deleted file mode 100644 index c91dd8b28ae..00000000000 --- a/Quality-of-Service.md +++ /dev/null @@ -1,162 +0,0 @@ -# Quality of service - -## Background -Please read the [About Quality of Service Settings](About-Quality-of-Service-Settings.md) page for background information about the Quality of Service settings available in ROS 2. - - -In this demo, we will spawn a node that publishes a camera image and another that subscribes to the image and shows it on the screen. -We will then simulate a lossy network connection between them and show how different quality of service settings handle the bad link. - -## Build/install the demo - -### From pre-compiled binaries - -Simply download the binary packages for your OS from the [installation page](Installation.md). - -### From source - -OpenCV is a prerequisite for the QoS demo. -See the [OpenCV documentation](http://docs.opencv.org/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.html#table-of-content-introduction) for installation instructions. -Follow the instructions on the [installation page](Installation.md#building-from-source) for your particular platform. - -## Run the demo - -Before running the demo, make sure you have a working webcam connected to your computer. - -Once you've installed ROS 2, if you're on Linux, source your setup.bash file: - -``` -. /setup.bash -``` -or if you're on Windows **cmd*: -``` -call /local_setup.bat -``` - -Then run: - -``` -ros2 run image_tools showimage -``` - -Nothing will happen yet. -`showimage` is a subscriber node that is waiting for a publisher on the `image` topic. - -Note: you have to close the `showimage` process with `Ctrl-C` later. -You can't just close the window. - -In a separate terminal, source the install file and run the publisher node: - -``` -ros2 run image_tools cam2image -``` -This will publish an image from your webcam. In case you don't have a camera attached to your computer, there is a commandline option which publishes predefined images. -``` -ros2 run image_tools cam2image -b -``` - -In this window, you'll see terminal output: - -``` -Publishing image #1 -Publishing image #2 -Publishing image #3 -... -``` - -A window will pop up with the title "view" showing your camera feed. -In the first window, you'll see output from the subscriber: - -``` -Received image #1 -Received image #2 -Received image #3 -... -``` - -Note for OS X users: If you these examples do not work or you receive an error like `ddsi_conn_write failed -1` then you'll need to increase your system wide UDP packet size: - -``` -$ sudo sysctl -w net.inet.udp.recvspace=209715 -$ sudo sysctl -w net.inet.udp.maxdgram=65500 -``` - -These changes will not persist a reboot. If you want the changes to persist, add these lines to `/etc/sysctl.conf` (create the file if it doesn't exist already): - -``` -net.inet.udp.recvspace=209715 -net.inet.udp.maxdgram=65500 -``` - -### Command line options - -In one of your terminals, add a -h flag to the original command: - -``` -ros2 run image_tools showimage -- -h -``` - -You'll see a list of the possible options you can pass to the demo. - -`-h`: The help message. - -`-r`: Reliability. -There are two options for this policy: reliable or best effort. -Reliable means that values may be reset and the underlying DDS publisher might block, in order for messages to get delivered in order. -Best effort means that messages will get sent as is, and they may get dropped or lost without effecting the behavior of the publisher. - -`-k`: History policy (the "k" stands for "keep"). -Determines how DDS buffers messages in the time between the user code that called `publish` and the time when the message actually gets sent. -There are two options for history: KEEP_ALL and KEEP_LAST. -KEEP_ALL will buffer all messages before they get sent. -KEEP_LAST limits the number of buffered messages to a depth specified by the user. - -`-d`: Queue depth. -Only used if the history policy is set to KEEP_LAST. -The queue depth determines the maximum number of not yet received messages that get buffered on the sender's side before messages start getting dropped. - -If you run `cam2image -h`, you'll see the same set of command line options and two extras: - -`-s`: Toggle displaying the input camera stream. -If you run `cam2image -s` by itself, you'll see a camera window. -If you also run `showimage`, you'll see two camera windows. - -`-x` and `-y`: Set the size of the camera feed (x sets the width, y sets the height). - -The default quality of service settings are tuned for maximum reliability: the reliability policy is reliable, and the history policy is "keep all". - -It's worth noting that both ends must have the same reliability settings for this to work. -If the consumer requires the publisher to be reliable, DDS will not match them and there won't be any exchange between them. - -We won't see much of a difference if we change the quality of service settings, since the publisher and subscriber are passing messages over inter-process communication, and messages are unlikely to get dropped if they are travelling within the same machine. - -### Add network traffic - -This next section is Linux-specific. -However, for OS X and Windows you can achieve a similar effect with the utilities "Network Link Conditioner" (part of the xcode tool suite) and "Clumsy" (http://jagt.github.io/clumsy/index.html), respectively, but they will not be covered in this tutorial. - -We are going to use the Linux network traffic control utility, `tc` (http://linux.die.net/man/8/tc). - -``` -sudo tc qdisc add dev lo root netem loss 5% -``` - -This magical incantation will simulate 5% packet loss over the local loopback device. -If you use a higher resolution of the images (e.g. `-x 640 -y 480`) you might want to try a lower packet loss rate (e.g. `1%`). - -Next we start the `cam2image` and `showimage`, and we'll soon notice that both programs seem to have slowed down the rate at which images are transmitted. -This is caused by the behavior of the default QoS settings. -Enforcing reliability on a lossy channel means that the publisher (in this case, `cam2image`) will resend the network packets until it receives acknowledgement from the consumer (i.e. `showimage`). - -Let's now try running both programs, but with more suitable settings. -First of all, we'll use the `-r 0` option to enable best effort communication. -The publisher will now just attempt to deliver the network packets, and don't expect acknowledgement from the consumer. -We see now that some of the frame on the `showimage` side were dropped, the frame numbers in the shell running `showimage` won't be consecutive anymore: - -![Best effort image transfer ](https://raw.githubusercontent.com/ros2/demos/master/image_tools/doc/qos-best-effort.png) - -When you're done, remember to delete the queueing discipline: - -``` -sudo tc qdisc delete dev lo root netem loss 5% -``` diff --git a/Quality-of-Service.rst b/Quality-of-Service.rst new file mode 100644 index 00000000000..420d84e7f8c --- /dev/null +++ b/Quality-of-Service.rst @@ -0,0 +1,179 @@ + +Quality of service +================== + +Background +---------- + +Please read the `About Quality of Service Settings ` page for background information about the Quality of Service settings available in ROS 2. + +In this demo, we will spawn a node that publishes a camera image and another that subscribes to the image and shows it on the screen. +We will then simulate a lossy network connection between them and show how different quality of service settings handle the bad link. + +Build/install the demo +---------------------- + +From pre-compiled binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Simply download the binary packages for your OS from the `installation page `. + +From source +^^^^^^^^^^^ + +OpenCV is a prerequisite for the QoS demo. +See the `OpenCV documentation `__ for installation instructions. +Follow the instructions on the `installation page ` for your particular platform. + +Run the demo +------------ + +Before running the demo, make sure you have a working webcam connected to your computer. + +Once you've installed ROS 2, if you're on Linux, source your setup.bash file: + +.. code-block:: + + . /setup.bash + +or if you're on Windows *\ *cmd*\ : + +.. code-block:: + + call /local_setup.bat + +Then run: + +.. code-block:: + + ros2 run image_tools showimage + +Nothing will happen yet. +``showimage`` is a subscriber node that is waiting for a publisher on the ``image`` topic. + +Note: you have to close the ``showimage`` process with ``Ctrl-C`` later. +You can't just close the window. + +In a separate terminal, source the install file and run the publisher node: + +.. code-block:: + + ros2 run image_tools cam2image + +This will publish an image from your webcam. In case you don't have a camera attached to your computer, there is a commandline option which publishes predefined images. + +.. code-block:: + + ros2 run image_tools cam2image -b + +In this window, you'll see terminal output: + +.. code-block:: + + Publishing image #1 + Publishing image #2 + Publishing image #3 + ... + +A window will pop up with the title "view" showing your camera feed. +In the first window, you'll see output from the subscriber: + +.. code-block:: + + Received image #1 + Received image #2 + Received image #3 + ... + +Note for OS X users: If you these examples do not work or you receive an error like ``ddsi_conn_write failed -1`` then you'll need to increase your system wide UDP packet size: + +.. code-block:: + + $ sudo sysctl -w net.inet.udp.recvspace=209715 + $ sudo sysctl -w net.inet.udp.maxdgram=65500 + +These changes will not persist a reboot. If you want the changes to persist, add these lines to ``/etc/sysctl.conf`` (create the file if it doesn't exist already): + +.. code-block:: + + net.inet.udp.recvspace=209715 + net.inet.udp.maxdgram=65500 + +Command line options +^^^^^^^^^^^^^^^^^^^^ + +In one of your terminals, add a -h flag to the original command: + +.. code-block:: + + ros2 run image_tools showimage -- -h + +You'll see a list of the possible options you can pass to the demo. + +``-h``\ : The help message. + +``-r``\ : Reliability. +There are two options for this policy: reliable or best effort. +Reliable means that values may be reset and the underlying DDS publisher might block, in order for messages to get delivered in order. +Best effort means that messages will get sent as is, and they may get dropped or lost without effecting the behavior of the publisher. + +``-k``\ : History policy (the "k" stands for "keep"). +Determines how DDS buffers messages in the time between the user code that called ``publish`` and the time when the message actually gets sent. +There are two options for history: KEEP_ALL and KEEP_LAST. +KEEP_ALL will buffer all messages before they get sent. +KEEP_LAST limits the number of buffered messages to a depth specified by the user. + +``-d``\ : Queue depth. +Only used if the history policy is set to KEEP_LAST. +The queue depth determines the maximum number of not yet received messages that get buffered on the sender's side before messages start getting dropped. + +If you run ``cam2image -h``\ , you'll see the same set of command line options and two extras: + +``-s``\ : Toggle displaying the input camera stream. +If you run ``cam2image -s`` by itself, you'll see a camera window. +If you also run ``showimage``\ , you'll see two camera windows. + +``-x`` and ``-y``\ : Set the size of the camera feed (x sets the width, y sets the height). + +The default quality of service settings are tuned for maximum reliability: the reliability policy is reliable, and the history policy is "keep all". + +It's worth noting that both ends must have the same reliability settings for this to work. +If the consumer requires the publisher to be reliable, DDS will not match them and there won't be any exchange between them. + +We won't see much of a difference if we change the quality of service settings, since the publisher and subscriber are passing messages over inter-process communication, and messages are unlikely to get dropped if they are travelling within the same machine. + +Add network traffic +^^^^^^^^^^^^^^^^^^^ + +This next section is Linux-specific. +However, for OS X and Windows you can achieve a similar effect with the utilities "Network Link Conditioner" (part of the xcode tool suite) and "Clumsy" (http://jagt.github.io/clumsy/index.html), respectively, but they will not be covered in this tutorial. + +We are going to use the Linux network traffic control utility, ``tc`` (http://linux.die.net/man/8/tc). + +.. code-block:: + + sudo tc qdisc add dev lo root netem loss 5% + +This magical incantation will simulate 5% packet loss over the local loopback device. +If you use a higher resolution of the images (e.g. ``-x 640 -y 480``\ ) you might want to try a lower packet loss rate (e.g. ``1%``\ ). + +Next we start the ``cam2image`` and ``showimage``\ , and we'll soon notice that both programs seem to have slowed down the rate at which images are transmitted. +This is caused by the behavior of the default QoS settings. +Enforcing reliability on a lossy channel means that the publisher (in this case, ``cam2image``\ ) will resend the network packets until it receives acknowledgement from the consumer (i.e. ``showimage``\ ). + +Let's now try running both programs, but with more suitable settings. +First of all, we'll use the ``-r 0`` option to enable best effort communication. +The publisher will now just attempt to deliver the network packets, and don't expect acknowledgement from the consumer. +We see now that some of the frame on the ``showimage`` side were dropped, the frame numbers in the shell running ``showimage`` won't be consecutive anymore: + + +.. image:: https://raw.githubusercontent.com/ros2/demos/master/image_tools/doc/qos-best-effort.png + :target: https://raw.githubusercontent.com/ros2/demos/master/image_tools/doc/qos-best-effort.png + :alt: Best effort image transfer + + +When you're done, remember to delete the queueing discipline: + +.. code-block:: + + sudo tc qdisc delete dev lo root netem loss 5% diff --git a/README.md b/README.md index 275a589f6a5..e8c8da5cf14 100644 --- a/README.md +++ b/README.md @@ -9,29 +9,29 @@ See below for more information on ROS 2. If you're looking for information on ROS 1 (i.e., ROS as it has existed for several years and what you might be using right now), check the [ROS website](http://www.ros.org) or the [documentation wiki](http://wiki.ros.org). -**Before you proceed here, please read the [features page](Features.md) to get an idea of what is in the current ROS 2 release.** +**Before you proceed here, please read the [features page](Features) to get an idea of what is in the current ROS 2 release.** ## Releases -See [the releases page](Releases.md). +See [the releases page](Releases). ## Installation -See [the installation page](Installation.md). +See [the installation page](Installation). ## Tutorials and Features ROS 2 is under heavy development. -You can check out the [tutorials page](Tutorials.md) to see a range of examples of what the system can do in its current state, if it fits your project *today* depending on the exact requirement. -For details of the current features, see [Features](Features.md). -If migrating code from ROS to ROS 2, check [the migration guide](Migration-guide.md). +You can check out the [tutorials page](Tutorials) to see a range of examples of what the system can do in its current state, if it fits your project *today* depending on the exact requirement. +For details of the current features, see [Features](Features). +If migrating code from ROS to ROS 2, check [the migration guide](Migration-guide). ## What's ahead ROS 2 is currently planning to release new versions every six month (which is twice as often as ROS 1) to give the community members an opportunity to provide early feedback on the evolving system. -See the [Roadmap](Roadmap.md) for details on the planned upcoming features for ROS 2. +See the [Roadmap](Roadmap) for details on the planned upcoming features for ROS 2. ## Contributing -See [the contributing page](Contributing.md) and [the developer guide](Developer-Guide.md) for details on how to contribute to ROS 2 developments. +See [the contributing page](Contributing) and [the developer guide](Developer-Guide) for details on how to contribute to ROS 2 developments. ## Reporting problems and asking questions -See [the contact page](Contact.md). +See [the contact page](Contact). # About ROS 2 Since ROS was started in 2007, a lot has changed in the robotics and ROS community. diff --git a/ROS-2-Client-Libraries.md b/ROS-2-Client-Libraries.rst similarity index 73% rename from ROS-2-Client-Libraries.md rename to ROS-2-Client-Libraries.rst index eed78528f0c..9961eb28fe8 100644 --- a/ROS-2-Client-Libraries.md +++ b/ROS-2-Client-Libraries.rst @@ -1,4 +1,7 @@ -## Overview + +Overview +-------- + Client libraries are the APIs that allow users to implement their ROS code. They are what users use to get access to ROS concepts such as nodes, topics, services, etc. Client libraries come in a variety of programming languages so that users may write ROS code in the language that is best-suited for their application. @@ -8,28 +11,33 @@ Nodes written using different client libraries are able to share messages with e In addition to the language-specific communication tools, client libraries expose to users the core functionality that makes ROS “ROS”. For example, here is a list of functionality that can typically be accessed through a client library: -- Names and namespaces -- Time (real or simulated) -- Parameters -- Console logging -- Threading model -- Intra-process communication -## Supported client libraries -The C++ client library (`rclcpp`) and the Python client library (`rclpy`) are both client libraries which utilize common functionality in the RCL. +* Names and namespaces +* Time (real or simulated) +* Parameters +* Console logging +* Threading model +* Intra-process communication + +Supported client libraries +-------------------------- + +The C++ client library (\ ``rclcpp``\ ) and the Python client library (\ ``rclpy``\ ) are both client libraries which utilize common functionality in the RCL. While the C++ and Python client libraries are maintained by the core ROS 2 team, members of the ROS 2 community have created additional client libraries: -- [JVM and Android](https://github.com/esteve/ros2_java) -- [Objective C and iOS](https://github.com/esteve/ros2_objc) -- [C#](https://github.com/firesurfer/rclcs) -- [Swift](https://github.com/younata/rclSwift) -- [Node.js](https://www.npmjs.com/package/rclnodejs) -- [Ada](https://github.com/ada-ros/ada4ros2) +* `JVM and Android `__ +* `Objective C and iOS `__ +* `C# `__ +* `Swift `__ +* `Node.js `__ +* `Ada `__ + +Common functionality: the RCL +----------------------------- -## Common functionality: the RCL Most of the functionality found in a client library is not specific to the programming language of the client library. For example, the behavior of parameters and the logic of namespaces should ideally be the same across all programming languages. Because of this, rather than implementing the common functionality from scratch, client libraries make use of a common core ROS Client Library (RCL) interface that implements logic and behavior of ROS concepts that is not language-specific. @@ -41,21 +49,27 @@ In addition to making the client libraries light-weight, an advantage of having If any changes are made to the logic/behavior of the functionality in the core RCL -- namespaces, for example -- all client libraries that use the RCL will have these changes reflected. Furthermore, having the common core means that maintaining multiple client libraries becomes less work when it comes to bug fixes. -[The API documentation for the RCL can be found here.](http://docs.ros2.org/latest/api/rcl/) +`The API documentation for the RCL can be found here. `__ +Language-specific functionality +------------------------------- -## Language-specific functionality Client library concepts that require language-specific features/properties are not implemented in the RCL but instead are implemented in each client library. For example, threading models used by “spin” functions will have implementations that are specific to the language of the client library. +Demo +---- + +For a walkthrough of the message exchange between a publisher using ``rclpy`` and a subscriber using ``rclcpp``\ , we encourage you to watch `this ROSCon talk `__ starting at 17:25 `(here are the slides) `__. -## Demo -For a walkthrough of the message exchange between a publisher using `rclpy` and a subscriber using `rclcpp`, we encourage you to watch [this ROSCon talk](https://vimeo.com/187696091) starting at 17:25 [(here are the slides)](http://roscon.ros.org/2016/presentations/ROSCon%202016%20-%20ROS%202%20Update.pdf). +Comparison to ROS 1 +------------------- -## Comparison to ROS 1 In ROS 1, all client libraries are developed "from the ground up". This allows for the ROS 1 Python client library to be implemented purely in Python, for example, which brings benefits of such as not needing to compile code. However, naming conventions and behaviors are not always consistent between client libraries, bug fixes have to be done in multiple places, and there is a lot of functionality that has only ever been implemented in one client library (e.g. UDPROS). -## Summary -By utilizing the common core ROS client library, client libraries written in a variety of programming languages are easier to write and have more consistent behavior. \ No newline at end of file +Summary +------- + +By utilizing the common core ROS client library, client libraries written in a variety of programming languages are easier to write and have more consistent behavior. diff --git a/ROS-2-On-boarding-Guide.md b/ROS-2-On-boarding-Guide.md deleted file mode 100644 index 7dc8c237b98..00000000000 --- a/ROS-2-On-boarding-Guide.md +++ /dev/null @@ -1,175 +0,0 @@ -# ROS 2 On-boarding Guide - -The purpose of this guide is supplement the on-boarding of new developers when they join the ROS 2 team. -It is mostly used by the ROS 2 team, but it might be useful for others as well. - -## Request access to the GitHub organizations - -Our code is federated across a few GitHub organizations, you'll want access to them so you can make pull requests with branches rather than forks: - -- https://github.com/ros2 -- https://github.com/ament -- https://github.com/osrf (optional, as-needed) - -## Request access to the buildfarm - -The build farm is hosted at: ci.ros2.org - -To request access send an email to ros@osrfoundation.org. - -### How to give access? - -Your GitHub username must be added with the same permissions as existing users to Jenkins (http://ci.ros2.org/configureSecurity/). -This can be done by any existing user. - -### How to access the machines running the ci.ros2.org? - -Only do this if you're working at OSRF or if you're asked to log into the machines. -To be able to ssh into the node hosted on AWS, you need give request access from Tully Foote (tfoote@osrfoundation.org). - -## Request access to the Google drive ROS2 folder - -Only do this if you're working at OSRF or need access to a particular document. -To request access send an email to ros@osrfoundation.org (anybody on the mailing list can share it). - -## Choose a DDS domain ID - -ROS2 uses DDS as the underlying transport and DDS supports a physical segmentation of the network based on the "domain ID" (it is used to calculate the multicast port. -We use a unique value for this on each machine to keep our ROS2 nodes from interfering from each other. -We expose this setting via the `ROS_DOMAIN_ID` environment variable and use a document to ensure we don't accidentally choose the same one as someone else. -This is, however, only important for people who will be working on the OSRF network, but it isn't a bad idea to set up at any organization with multiple ROS 2 users on the same network. - -### Get a Personal ROS_DOMAIN_ID - -Go to the [ROS 2 Assigned Domain ID's Spreadsheet](https://docs.google.com/spreadsheets/d/1YuDSH1CeySBP4DaCX4KoCDW_lZY4PuFWUu4MW6Vsp1s/edit) and reserve an ID, or email ros@osrfoundation.org and ask for one to be allocated to you. -Numbers under 128 are preferred. - -To ensure it is always set, add this line to your `~/.bashrc` or equivalent: - -```bash -export ROS_DOMAIN_ID= -``` - -## Watching ROS 2 Repositories - -We try to spread our responsibilities out across the team and so we ask everyone to watch the main repositories for ROS 2. - -- What am I currently watching? - - https://github.com/watching -- How do I watch a repository? - - https://help.github.com/articles/watching-repositories/ -- Which repositories should I watch? - - All the repositories listed in the [`ros2.repos` file](https://github.com/ros2/ros2/blob/master/ros2.repos), included the commented out ones, - - Also all of these extra repositories from the ROS 2 organization: - - https://github.com/ros2/ci - - https://github.com/ros2/design - - https://github.com/ros2/ros_astra_camera - - https://github.com/ros2/ros_core_documentation - - https://github.com/ros2/ros2 - - https://github.com/ros2/sros2 - - https://github.com/ros2/turtlebot2_demo - - https://github.com/ros2/joystick_drivers - -## Developer Workflow - -We track all open tickets and current PRs using waffle.io: https://waffle.io/ros2/ros2 - -Higher level tasks are tracked on the internal (private) Jira: https://osrfoundation.atlassian.net/projects/ROS2 - -The usual workflow is (this list is a work in progress): - -- Discuss design (GitHub ticket, and a meeting if needed) -- Assign implementation to a team member -- Write implementation on a feature branch - - Please check out the [developer guide](Developer-Guide.md) for guidelines and best practices -- Write tests -- Enable and run linters -- Run tests locally using `colcon test` (see [colcon tutorial](Colcon-Tutorial.md)) -- Once everything builds locally without warnings and all tests are passing, run CI on your feature branch: - - Go to ci.ros2.org - - Log in (top right corner) - - Click on the `ci_launcher` job - - Click "Build with Parameters" (left column) - - In the first box "CI_BRANCH_TO_TEST" enter your feature branch name - - Hit the `build` button -- If built without warnings, errors and test failures, post the links of your jobs on your PR or high level ticket aggregating all your PRs (example [here](https://github.com/ros2/rcl/pull/106#issuecomment-271119200)) - - Note that the markdown for these badges is in the console output of the `ci_launcher` job -- To get the PR reviewed, you need to put the label "in review": - - Through github interface: - - Click on "" next to labels - - Remove "in progress" label if applicable - - Add "in review" label - - Through waffle: - - Drag your PR to the "in review" column -- When the PR has been approved: - - the person who submitted the PR merges it using "Squash and Merge" option so that we keep a clean history - - If the commits deserve to keep separated: squash all the nitpick/linters/typo ones together and merge the remaining set - - Note: each PR should target a specific feature so Squash and Merge should make sense 99% of the time -- Delete the branch once merged - -## Waffle.io How-to - -Here are some tips on how to use our Kanban board on waffle.io: - -- Assigning labels: drag and drop cards to the column with the label you want to assign -- Connecting Issues/PR: Waffle allows to connect cards together using keywords - - Note1: The keywords need to be placed in the 1st comment of the GitHub ticket - - Note2: Waffle uses the "simplified" GitHub reference and not the full URL to connect card. - - Does not work: - - "connects to https://github.com/ros2/rosidl/issues/216" - - Works: - - In the same repo: "connects to #216" - - In another repo: "connects to ros2/rosidl#216" - -## Build Farm Introduction - -The build farm is located at [ci.ros2.org](http://ci.ros2.org/). - -Every night we run nightly jobs which build and run all the tests in various scenarios on various platforms. -Additionally, we test all pull requests against these platforms before merging. - -This is the current set of target platforms and architectures, though it evolves overtime: - -- Ubuntu 16.04 Xenial - - amd64 - - aarch64 -- macOS 10.12 Sierra - - amd64 -- Windows 10 - - amd64 - -There several categories of jobs on the buildfarm: - -- manual jobs (triggered manually by developers): - - ci_linux: build + test the code on Ubuntu Xenial - - ci_linux-aarch64: build + test the code on Ubuntu Xenial on an ARM 64-bit machine (aarch64) - - ci_osx: build + test the code on MacOS 10.12 - - ci_windows: build + test the code on Windows 10 - - ci_launcher: trigger all the jobs listed above -- nightly (run every night): - - Debug: build + test the code with CMAKE_BUILD_TYPE=Debug - - nightly_linux_debug - - nightly_linux-aarch64_debug - - nightly_osx_debug - - nightly_win_deb - - Release: build + test the code with CMAKE_BUILD_TYPE=Release - - nightly_linux_release - - nightly_linux-aarch64_release - - nightly_osx_release - - nightly_win_rel - - Repeated: build then run each test up to 20 times or until failed (aka flakyness hunter) - - nightly_linux_repeated - - nightly_linux-aarch64_repeated - - nightly_osx_repeated - - nightly_win_rep - - Coverage: - - nightly_linux_coverage: build + test the code + analyses coverage for c/c++ and python - - results are exported as a cobertura report -- packaging (run every night, against fastrtps; result is bundled into an archive): - - packaging_linux - - packaging_osx - - Packaging_windows - -## Learning ROS2 concepts at a high level - -All ROS2 design documents are available at http://design.ros2.org/ and there is some generated documentation at http://docs.ros2.org/ diff --git a/ROS-2-On-boarding-Guide.rst b/ROS-2-On-boarding-Guide.rst new file mode 100644 index 00000000000..b5e70ed0c2e --- /dev/null +++ b/ROS-2-On-boarding-Guide.rst @@ -0,0 +1,239 @@ + +ROS 2 On-boarding Guide +======================= + +The purpose of this guide is supplement the on-boarding of new developers when they join the ROS 2 team. +It is mostly used by the ROS 2 team, but it might be useful for others as well. + +Request access to the GitHub organizations +------------------------------------------ + +Our code is federated across a few GitHub organizations, you'll want access to them so you can make pull requests with branches rather than forks: + + +* https://github.com/ros2 +* https://github.com/ament +* https://github.com/osrf (optional, as-needed) + +Request access to the buildfarm +------------------------------- + +The build farm is hosted at: ci.ros2.org + +To request access send an email to ros@osrfoundation.org. + +How to give access? +^^^^^^^^^^^^^^^^^^^ + +Your GitHub username must be added with the same permissions as existing users to Jenkins (http://ci.ros2.org/configureSecurity/). +This can be done by any existing user. + +How to access the machines running the ci.ros2.org? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Only do this if you're working at OSRF or if you're asked to log into the machines. +To be able to ssh into the node hosted on AWS, you need give request access from Tully Foote (tfoote@osrfoundation.org). + +Request access to the Google drive ROS2 folder +---------------------------------------------- + +Only do this if you're working at OSRF or need access to a particular document. +To request access send an email to ros@osrfoundation.org (anybody on the mailing list can share it). + +Choose a DDS domain ID +---------------------- + +ROS2 uses DDS as the underlying transport and DDS supports a physical segmentation of the network based on the "domain ID" (it is used to calculate the multicast port. +We use a unique value for this on each machine to keep our ROS2 nodes from interfering from each other. +We expose this setting via the ``ROS_DOMAIN_ID`` environment variable and use a document to ensure we don't accidentally choose the same one as someone else. +This is, however, only important for people who will be working on the OSRF network, but it isn't a bad idea to set up at any organization with multiple ROS 2 users on the same network. + +Get a Personal ROS_DOMAIN_ID +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Go to the `ROS 2 Assigned Domain ID's Spreadsheet `__ and reserve an ID, or email ros@osrfoundation.org and ask for one to be allocated to you. +Numbers under 128 are preferred. + +To ensure it is always set, add this line to your ``~/.bashrc`` or equivalent: + +.. code-block:: bash + + export ROS_DOMAIN_ID= + +Watching ROS 2 Repositories +--------------------------- + +We try to spread our responsibilities out across the team and so we ask everyone to watch the main repositories for ROS 2. + + +* What am I currently watching? + + * https://github.com/watching + +* How do I watch a repository? + + * https://help.github.com/articles/watching-repositories/ + +* Which repositories should I watch? + + * All the repositories listed in the `\ ``ros2.repos`` file `__\ , included the commented out ones, + * Also all of these extra repositories from the ROS 2 organization: + + * https://github.com/ros2/ci + * https://github.com/ros2/design + * https://github.com/ros2/ros_astra_camera + * https://github.com/ros2/ros_core_documentation + * https://github.com/ros2/ros2 + * https://github.com/ros2/sros2 + * https://github.com/ros2/turtlebot2_demo + * https://github.com/ros2/joystick_drivers + +Developer Workflow +------------------ + +We track all open tickets and current PRs using waffle.io: https://waffle.io/ros2/ros2 + +Higher level tasks are tracked on the internal (private) Jira: https://osrfoundation.atlassian.net/projects/ROS2 + +The usual workflow is (this list is a work in progress): + + +* Discuss design (GitHub ticket, and a meeting if needed) +* Assign implementation to a team member +* Write implementation on a feature branch + + * Please check out the `developer guide ` for guidelines and best practices + +* Write tests +* Enable and run linters +* Run tests locally using ``colcon test`` (see `colcon tutorial `\ ) +* Once everything builds locally without warnings and all tests are passing, run CI on your feature branch: + + * Go to ci.ros2.org + * Log in (top right corner) + * Click on the ``ci_launcher`` job + * Click "Build with Parameters" (left column) + * In the first box "CI_BRANCH_TO_TEST" enter your feature branch name + * Hit the ``build`` button + +* If built without warnings, errors and test failures, post the links of your jobs on your PR or high level ticket aggregating all your PRs (example `here `__\ ) + + * Note that the markdown for these badges is in the console output of the ``ci_launcher`` job + +* To get the PR reviewed, you need to put the label "in review": + + * Through github interface: + + * Click on "" next to labels + * Remove "in progress" label if applicable + * Add "in review" label + + * Through waffle: + + * Drag your PR to the "in review" column + +* When the PR has been approved: + + * the person who submitted the PR merges it using "Squash and Merge" option so that we keep a clean history + + * If the commits deserve to keep separated: squash all the nitpick/linters/typo ones together and merge the remaining set + + * Note: each PR should target a specific feature so Squash and Merge should make sense 99% of the time + +* Delete the branch once merged + +Waffle.io How-to +---------------- + +Here are some tips on how to use our Kanban board on waffle.io: + + +* Assigning labels: drag and drop cards to the column with the label you want to assign +* Connecting Issues/PR: Waffle allows to connect cards together using keywords + + * Note1: The keywords need to be placed in the 1st comment of the GitHub ticket + * Note2: Waffle uses the "simplified" GitHub reference and not the full URL to connect card. + + * Does not work: + + * "connects to https://github.com/ros2/rosidl/issues/216" + + * Works: + + * In the same repo: "connects to #216" + * In another repo: "connects to ros2/rosidl#216" + +Build Farm Introduction +----------------------- + +The build farm is located at `ci.ros2.org `__. + +Every night we run nightly jobs which build and run all the tests in various scenarios on various platforms. +Additionally, we test all pull requests against these platforms before merging. + +This is the current set of target platforms and architectures, though it evolves overtime: + + +* Ubuntu 16.04 Xenial + + * amd64 + * aarch64 + +* macOS 10.12 Sierra + + * amd64 + +* Windows 10 + + * amd64 + +There several categories of jobs on the buildfarm: + + +* manual jobs (triggered manually by developers): + + * ci_linux: build + test the code on Ubuntu Xenial + * ci_linux-aarch64: build + test the code on Ubuntu Xenial on an ARM 64-bit machine (aarch64) + * ci_osx: build + test the code on MacOS 10.12 + * ci_windows: build + test the code on Windows 10 + * ci_launcher: trigger all the jobs listed above + +* nightly (run every night): + + * Debug: build + test the code with CMAKE_BUILD_TYPE=Debug + + * nightly_linux_debug + * nightly_linux-aarch64_debug + * nightly_osx_debug + * nightly_win_deb + + * Release: build + test the code with CMAKE_BUILD_TYPE=Release + + * nightly_linux_release + * nightly_linux-aarch64_release + * nightly_osx_release + * nightly_win_rel + + * Repeated: build then run each test up to 20 times or until failed (aka flakyness hunter) + + * nightly_linux_repeated + * nightly_linux-aarch64_repeated + * nightly_osx_repeated + * nightly_win_rep + + * Coverage: + + * nightly_linux_coverage: build + test the code + analyses coverage for c/c++ and python + + * results are exported as a cobertura report + +* packaging (run every night, against fastrtps; result is bundled into an archive): + + * packaging_linux + * packaging_osx + * Packaging_windows + +Learning ROS2 concepts at a high level +-------------------------------------- + +All ROS2 design documents are available at http://design.ros2.org/ and there is some generated documentation at http://docs.ros2.org/ diff --git a/Rclpy-Import-error-hint.md b/Rclpy-Import-error-hint.md deleted file mode 100644 index 33fd18a178d..00000000000 --- a/Rclpy-Import-error-hint.md +++ /dev/null @@ -1,6 +0,0 @@ -# Import failing even with library present on the system - -Sometimes `rclpy` fails to be imported because of some missing DLLs on your system. -If so make sure to install all the dependencies listed in the "Installing prerequisites" sections of the installation instructions ([Windows](Windows-Install-Binary.md#installing-prerequisites), [MacOS](OSX-Install-Binary.md#installing-prerequisites), [Linux](Linux-Install-Binary.md#installing-prerequisites)). - -If you are installing from binaries, you may need to update your dependencies: they must be the same version as those used to build the binaries. diff --git a/Rclpy-Import-error-hint.rst b/Rclpy-Import-error-hint.rst new file mode 100644 index 00000000000..c51bdb77629 --- /dev/null +++ b/Rclpy-Import-error-hint.rst @@ -0,0 +1,8 @@ + +Import failing even with library present on the system +====================================================== + +Sometimes ``rclpy`` fails to be imported because of some missing DLLs on your system. +If so make sure to install all the dependencies listed in the "Installing prerequisites" sections of the installation instructions (\ `Windows `\ , `MacOS `\ , `Linux `\ ). + +If you are installing from binaries, you may need to update your dependencies: they must be the same version as those used to build the binaries. diff --git a/Real-Time-Programming.md b/Real-Time-Programming.rst similarity index 62% rename from Real-Time-Programming.md rename to Real-Time-Programming.rst index 4b7ebf29abf..b33c18b5c93 100644 --- a/Real-Time-Programming.md +++ b/Real-Time-Programming.rst @@ -1,21 +1,24 @@ -## Background + +Background +---------- Real-time computing is a key feature of many robotics systems, particularly safety- and mission-critical applications such as autonomous vehicles, spacecrafts, and industrial manufacturing. We are designing and prototyping ROS 2 with real-time performance constraints in mind, since this is a requirement that was not considered in the early stages of ROS 1 and it is now intractable to refactor ROS 1 to be real-time friendly. -[This document](http://design.ros2.org/articles/realtime_background.html) outlines the requirements of real-time computing and best practices for software engineers. tl;dr: +`This document `__ outlines the requirements of real-time computing and best practices for software engineers. tl;dr: To make a real-time computer system, our real-time loop must update periodically to meet deadlines. We can only tolerate a small margin of error on these deadlines (our maximum allowable jitter). To do this, we must avoid nondeterministic operations in the execution path, things like: pagefault events, dynamic memory allocation/deallocation, and synchronization primitives that block indefinitely. -A classic example of a controls problem commonly solved by real-time computing is balancing an [inverted pendulum](https://en.wikipedia.org/wiki/Inverted_pendulum). +A classic example of a controls problem commonly solved by real-time computing is balancing an `inverted pendulum `__. If the controller blocked for an unexpectedly long amount of time, the pendulum would fall down or go unstable. But if the controller reliably updates at a rate faster than the motor controlling the pendulum can operate, the pendulum will successfully adapt react to sensor data to balance the pendulum. Now that you know everything about real-time computing, let's try a demo! -## Install and run the demo +Install and run the demo +------------------------ The real-time demo was written with Linux operating systems in mind, since many members of the ROS community doing real-time computing use Xenomai or RT_PREEMPT as their real-time solutions. Since many of the operations done in the demo to optimize performance or OS-specific, the demo only builds and runs on Linux systems. @@ -23,91 +26,94 @@ Since many of the operations done in the demo to optimize performance or OS-spec Also this must be built from source using a the static DDS API. **Currently the only supported implementation is Connext**. -First, follow the instructions to build ROS 2 [from source](Linux-Development-Setup) using Connext DDS as the middleware. - - +First, follow the instructions to build ROS 2 `from source ` using Connext DDS as the middleware. - -### Run the tests +Run the tests +^^^^^^^^^^^^^ **Before you run make sure you have at least 8Gb of RAM free. With the memory locking, swap will not work anymore.** Source your ROS 2 setup.bash. -Run the demo binary, and redirect the output. You may want to use `sudo` in case you get permission error: -``` -pendulum_demo > output.txt -``` +Run the demo binary, and redirect the output. You may want to use ``sudo`` in case you get permission error: + +.. code-block:: -## What the heck just happened? + pendulum_demo > output.txt + +What the heck just happened? +---------------------------- First, even though you redirected stdout, you will see some output to the console (from stderr): -``` -mlockall failed: Cannot allocate memory -Couldn't lock all cached virtual memory. -Pagefaults from reading pages not yet mapped into RAM will be recorded. -``` +.. code-block:: + + mlockall failed: Cannot allocate memory + Couldn't lock all cached virtual memory. + Pagefaults from reading pages not yet mapped into RAM will be recorded. -After the initialization stage of the demo program, it will attempt to lock all cached memory into RAM and prevent future dynamic memory allocations using `mlockall`. +After the initialization stage of the demo program, it will attempt to lock all cached memory into RAM and prevent future dynamic memory allocations using ``mlockall``. This is to prevent pagefaults from loading lots of new memory into RAM. -(See [the realtime design article](http://design.ros2.org/articles/realtime_background.html#memory-management) for more information.) +(See `the realtime design article `__ for more information.) The demo will continue on as usual when this occurs. At the bottom of the output.txt file generated by the demo, you'll see the number of pagefaults encountered during execution: -``` -rttest statistics: - - Minor pagefaults: 20 - - Major pagefaults: 0 -``` +.. code-block:: + + rttest statistics: + - Minor pagefaults: 20 + - Major pagefaults: 0 If we want those pagefaults to go away, we'll have to... -### Adjust permissions for memory locking +Adjust permissions for memory locking +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Add to ``/etc/security/limits.conf`` (as sudo): -Add to `/etc/security/limits.conf` (as sudo): +.. code-block:: -``` - - memlock -``` + - memlock -A limit of `-1` is unlimited. -If you choose this, you may need to accompany it with `ulimit -l unlimited` after editing the file. +A limit of ``-1`` is unlimited. +If you choose this, you may need to accompany it with ``ulimit -l unlimited`` after editing the file. After saving the file, log out and log back in. -Then rerun the `pendulum_demo` invocation. +Then rerun the ``pendulum_demo`` invocation. You'll either see zero pagefaults in your output file, or an error saying that a bad_alloc exception was caught. If this happened, you didn't have enough free memory available to lock the memory allocated for the process into RAM. You'll need to install more RAM in your computer to see zero pagefaults! -### Output overview +Output overview +^^^^^^^^^^^^^^^ -To see more output, we have to run the `pendulum_logger` node. +To see more output, we have to run the ``pendulum_logger`` node. -In one shell with your `install/setup.bash` sourced, invoke: +In one shell with your ``install/setup.bash`` sourced, invoke: -`pendulum_logger` +``pendulum_logger`` You should see the output message: -``` -Logger node initialized. -``` -In another shell with setup.bash sourced, invoke `pendulum_demo` again. +.. code-block:: + + Logger node initialized. + +In another shell with setup.bash sourced, invoke ``pendulum_demo`` again. As soon as this executable starts, you should see the other shell constantly printing output: -``` -Commanded motor angle: 1.570796 -Actual motor angle: 1.570796 -Mean latency: 210144.000000 ns -Min latency: 4805 ns -Max latency: 578137 ns -Minor pagefaults during execution: 0 -Major pagefaults during execution: 0 -``` +.. code-block:: + + Commanded motor angle: 1.570796 + Actual motor angle: 1.570796 + Mean latency: 210144.000000 ns + Min latency: 4805 ns + Max latency: 578137 ns + Minor pagefaults during execution: 0 + Major pagefaults during execution: 0 The demo is controlling a very simple inverted pendulum simulation. The pendulum simulation calculates its position in its own thread. @@ -116,25 +122,26 @@ Another ROS node acts as a simple PID controller and calculates the next command The logger node periodically prints out the pendulum's state and the runtime performance statistics of the demo during its execution phase. -After the `pendulum_demo` is finished, you'll have to CTRL-C out of the logger node to exit. +After the ``pendulum_demo`` is finished, you'll have to CTRL-C out of the logger node to exit. + +Latency +^^^^^^^ -### Latency +At the ``pendulum_demo`` execution,, you'll see the final statistics collected for the demo: -At the `pendulum_demo` execution,, you'll see the final statistics collected for the demo: +.. code-block:: -``` -rttest statistics: - - Minor pagefaults: 0 - - Major pagefaults: 0 - Latency (time after deadline was missed): - - Min: 3354 ns - - Max: 2752187 ns - - Mean: 19871.8 ns - - Standard deviation: 1.35819e+08 + rttest statistics: + - Minor pagefaults: 0 + - Major pagefaults: 0 + Latency (time after deadline was missed): + - Min: 3354 ns + - Max: 2752187 ns + - Mean: 19871.8 ns + - Standard deviation: 1.35819e+08 -PendulumMotor received 985 messages -PendulumController received 987 messages -``` + PendulumMotor received 985 messages + PendulumController received 987 messages The latency fields show you the minimum, maximum, and average latency of the update loop in nanoseconds. Here, latency means the amount of time after the update was expected to occur. @@ -146,29 +153,31 @@ So, our average latency was really good in this run, but the maximum latency was We may be suffering from a non-deterministic scheduler. If you're running a vanilla Linux system and you don't have the RT_PREEMPT kernel installed, you probably won't be able to meet the real-time goal we set for ourselves, because the Linux scheduler won't allow you to arbitrarily pre-empt threads at the user level. -See the [realtime design article](https://github.com/ros2/design/blob/gh-pages/articles/realtime.md#multithreaded-programming-and-synchronization) for more information. +See the `realtime design article `__ for more information. The demo attempts to set the scheduler and thread priority of the demo to be suitable for real-time performance. If this operation failed, you'll see an error message: "Couldn't set scheduling priority and policy: Operation not permitted". You can get slightly better performance by following the instructions in the next section: -### Setting permissions for the scheduler +Setting permissions for the scheduler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Add to `/etc/security/limits.conf` (as sudo): +Add to ``/etc/security/limits.conf`` (as sudo): -``` - - rtprio 98 -``` +.. code-block:: + + - rtprio 98 The range of the rtprio (real-time priority) field is 0-99. However, do NOT set the limit to 99 because then your processes could interfere with important system processes that run at the top priority (e.g. watchdog). This demo will attempt to run the control loop at priority 98. -## Plotting results +Plotting results +---------------- You can plot the latency and pagefault statistics that are collected in this demo after the demo runs. -Because the code has been instrumented with [rttest](https://github.com/ros2/rttest), there are useful command line tools available to us: +Because the code has been instrumented with `rttest `__\ , there are useful command line tools available to us: -i Specify how many iterations to run the real-time loop. Default is 1000. @@ -182,22 +191,22 @@ Default update period is 1ms. Run the demo again with the name a file to save results to: -``` -pendulum_demo -f pendulum_demo_results -``` +.. code-block:: + + pendulum_demo -f pendulum_demo_results -Then run the `rttest_plot` script on the resulting file: +Then run the ``rttest_plot`` script on the resulting file: -``` -rttest_plot pendulum_demo_results -``` +.. code-block:: + + rttest_plot pendulum_demo_results This script will produce three files: -``` -pendulum_demo_results_plot_latency.svg -pendulum_demo_results_plot_majflts.svg -pendulum_demo_results_plot_minflts.svg -``` +.. code-block:: + + pendulum_demo_results_plot_latency.svg + pendulum_demo_results_plot_majflts.svg + pendulum_demo_results_plot_minflts.svg You can view these plots in an image viewer of your choice. diff --git a/Release-Ardent-Apalone.md b/Release-Ardent-Apalone.md deleted file mode 100644 index 077ed100f23..00000000000 --- a/Release-Ardent-Apalone.md +++ /dev/null @@ -1,54 +0,0 @@ -### ROS 2 Ardent Apalone (codename 'ardent'; December 2017) - -Welcome to the first non-beta release of ROS 2 software named *Ardent Apalone*! - -### Supported Platforms - -This version of ROS 2 is supported on three platforms: -- Ubuntu 16.04 (Xenial) -- Mac OS X 10.12 (Sierra) -- Windows 10 - -Binary packages as well as instructions for how to compile from source are provided for all 3 platforms (see [install instructions](Installation.md) as well as [documentation](http://docs.ros2.org/ardent/)). - -### Features - -- Distributed discovery, publish / subscribe, request / response communication - - Provided by a C API - - Implemented using different vendors: - - eProsima's FastRTPS as well as ADLINK's OpenSplice (from binary and source) - - RTI's Connext (only from source) - - Numerous quality of service settings for handling non-ideal networks - - DDS Security support (with Connext and FastRTPS) -- C++ and Python 3 client libraries - - Sharing common code in C to unify the implementation - - Execution model separated from the nodes, composable nodes - - Node-specific parameters (only in C++ atm) - - Life cycle (only in C++ atm) - - Optionally intra-process communication using the same API (only in C++) -- Message definitions (with bounded arrays and strings as well as default values) -- Command line tools (e.g. `ros2 run`) -- `rviz` with a few display types (the Windows version will likely follow in a few weeks) -- File system-based resource index (querying information without recursive crawling) -- Realtime safe code paths for pub / sub (with compatible DDS implementations only) -- Bridge between ROS 1 and ROS 2 -- HSR demo [see Beta 3](Beta3-Overview) -- Turtlebot demo [see Beta 2](Beta2-Overview) - -For a more detailed description please see the [Features](Features.md) page. - -#### Changes since Beta 3 release - -Improvements since the Beta 3 release: -- `rviz` -- Different initialization options for message data structures in C++ (see [design doc](http://design.ros2.org/articles/generated_interfaces_cpp.html#constructors)) -- Logging API improvements, now also used in the demos -- Time support in C++ with different clocks -- wait-for-service support in the Python client library -- Draft implementation of [REP 149](http://www.ros.org/reps/rep-0149.html) specifying format 3 of the package manifest files - -### Known Issues -* FastRTPS performance with larger data like the image demo -* Using Connext it is currently not allowed for two topics with the same base name but different namespaces to have a different type (see [issue](https://github.com/ros2/rmw_connext/issues/234)). -* Listing of node names (e.g. using `ros2 node list`) does not work across some rmw implementations. -* On Windows Python launch files might hang when trying to abort using `Ctrl-C` (see [issue](https://github.com/ros2/launch/issues/64)). In order to continue using the shell which is blocked by the hanging command you might want to end the hanging Python process using the process monitor. diff --git a/Release-Ardent-Apalone.rst b/Release-Ardent-Apalone.rst new file mode 100644 index 00000000000..75681abf242 --- /dev/null +++ b/Release-Ardent-Apalone.rst @@ -0,0 +1,73 @@ + +ROS 2 Ardent Apalone (codename 'ardent'; December 2017) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Welcome to the first non-beta release of ROS 2 software named *Ardent Apalone*\ ! + +Supported Platforms +^^^^^^^^^^^^^^^^^^^ + +This version of ROS 2 is supported on three platforms: + + +* Ubuntu 16.04 (Xenial) +* Mac OS X 10.12 (Sierra) +* Windows 10 + +Binary packages as well as instructions for how to compile from source are provided for all 3 platforms (see `install instructions ` as well as `documentation `__\ ). + +Features +^^^^^^^^ + + +* Distributed discovery, publish / subscribe, request / response communication + + * Provided by a C API + * Implemented using different vendors: + + * eProsima's FastRTPS as well as ADLINK's OpenSplice (from binary and source) + * RTI's Connext (only from source) + + * Numerous quality of service settings for handling non-ideal networks + * DDS Security support (with Connext and FastRTPS) + +* C++ and Python 3 client libraries + + * Sharing common code in C to unify the implementation + * Execution model separated from the nodes, composable nodes + * Node-specific parameters (only in C++ atm) + * Life cycle (only in C++ atm) + * Optionally intra-process communication using the same API (only in C++) + +* Message definitions (with bounded arrays and strings as well as default values) +* Command line tools (e.g. ``ros2 run``\ ) +* ``rviz`` with a few display types (the Windows version will likely follow in a few weeks) +* File system-based resource index (querying information without recursive crawling) +* Realtime safe code paths for pub / sub (with compatible DDS implementations only) +* Bridge between ROS 1 and ROS 2 +* HSR demo `see Beta 3 ` +* Turtlebot demo `see Beta 2 ` + +For a more detailed description please see the `Features ` page. + +Changes since Beta 3 release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Improvements since the Beta 3 release: + + +* ``rviz`` +* Different initialization options for message data structures in C++ (see `design doc `__\ ) +* Logging API improvements, now also used in the demos +* Time support in C++ with different clocks +* wait-for-service support in the Python client library +* Draft implementation of `REP 149 `__ specifying format 3 of the package manifest files + +Known Issues +^^^^^^^^^^^^ + + +* FastRTPS performance with larger data like the image demo +* Using Connext it is currently not allowed for two topics with the same base name but different namespaces to have a different type (see `issue `__\ ). +* Listing of node names (e.g. using ``ros2 node list``\ ) does not work across some rmw implementations. +* On Windows Python launch files might hang when trying to abort using ``Ctrl-C`` (see `issue `__\ ). In order to continue using the shell which is blocked by the hanging command you might want to end the hanging Python process using the process monitor. diff --git a/Release-Bouncy-Bolson.md b/Release-Bouncy-Bolson.md deleted file mode 100644 index d4637a05b9d..00000000000 --- a/Release-Bouncy-Bolson.md +++ /dev/null @@ -1,52 +0,0 @@ -### ROS 2 Bouncy Bolson (codename 'bouncy'; June 2018) - -Welcome to the latest release of ROS 2 software named *Bouncy Bolson*! - -### Supported Platforms - -This version of ROS 2 is supported on four platforms (see [REP 2000](http://www.ros.org/reps/rep-2000.html#bouncy-bolson-june-2018-june-2019)): -- Ubuntu 18.04 (Bionic) - - Debian packages for amd64 as well as arm64 -- Ubuntu 16.04 (Xenial) - - no Debian packages but building from source is supported -- Mac OS X 10.12 (Sierra) -- Windows 10 with Visual Studio 2017 - -Binary packages as well as instructions for how to compile from source are provided (see [install instructions](Installation.md) as well as [documentation](http://docs.ros2.org/bouncy/)). - -### Features - -#### New features in this ROS 2 release - -- [New launch system](Launch-system.md) featuring a much more capable and flexible Python API. -- Parameters can be passed as [command line arguments](Node-arguments.md) to C++ executables. -- Static remapping via [command line arguments](Node-arguments.md). -- Various improvements to the Python client library. -- Support for publishing and subscribing to serialized data. - This is the foundation for the upcoming work towards a native rosbag implementation. -- More [command line tools](Introspection-with-command-line-tools.md), e.g. for working with parameters and lifecycle states. -- Binary packages / fat archives support three RMW implementations by default (without the need to build from source): - - eProsima's FastRTPS (default) - - RTI's Connext - - ADLINK's OpenSplice - -For an overview of all features available, including those from earlier releases, please see the [Features](Features.md) page. - -#### Changes since the Ardent release - -Changes since the [Ardent Apalone](Release-Ardent-Apalone.md) release: -- The Python package `launch` has been redesigned. - The previous Python API has been moved into a submodule `launch.legacy`. - You can update existing launch files to continue to use the legacy API if a transition to the new Python API is not desired. -- The ROS topic names containing namespaces are mapped to DDS topics including their namespaces. - DDS partitions are not being used anymore for this. -- The recommended build tool is now `colcon` instead of `ament_tools`. - This switch has no [implications](http://design.ros2.org/articles/build_tool.html#implications) for the code in each ROS 2 package. - The install instructions have been updated and the [read-the-docs page](http://colcon.readthedocs.io/en/latest/migration/ament_tools.html) describes how to map an existing `ament_tools` call to `colcon`. -- The argument order of [this `rclcpp::Node::create_subscription()` signature](http://docs.ros2.org/bouncy/api/rclcpp/classrclcpp_1_1_node.html#a283fb006c46470cf43a4ae5ef4a16ccd) has been modified. - -### Known Issues - -- New-style launch files [may hang on shutdown](https://github.com/ros2/launch/issues/89) for some combinations of platform and RMW implementation. -- Static remapping of namespaces [not working correctly](https://github.com/ros2/rcl/issues/262) when addressed to a particular node. -- [Opensplice error messages may be printed](https://github.com/ros2/rmw_opensplice/issues/237) when using `ros2 param` and `ros2 lifecycle` command-line tools. diff --git a/Release-Bouncy-Bolson.rst b/Release-Bouncy-Bolson.rst new file mode 100644 index 00000000000..00e69e44cd0 --- /dev/null +++ b/Release-Bouncy-Bolson.rst @@ -0,0 +1,70 @@ + +ROS 2 Bouncy Bolson (codename 'bouncy'; June 2018) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Welcome to the latest release of ROS 2 software named *Bouncy Bolson*\ ! + +Supported Platforms +^^^^^^^^^^^^^^^^^^^ + +This version of ROS 2 is supported on four platforms (see `REP 2000 `__\ ): + + +* Ubuntu 18.04 (Bionic) + + * Debian packages for amd64 as well as arm64 + +* Ubuntu 16.04 (Xenial) + + * no Debian packages but building from source is supported + +* Mac OS X 10.12 (Sierra) +* Windows 10 with Visual Studio 2017 + +Binary packages as well as instructions for how to compile from source are provided (see `install instructions ` as well as `documentation `__\ ). + +Features +^^^^^^^^ + +New features in this ROS 2 release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* `New launch system ` featuring a much more capable and flexible Python API. +* Parameters can be passed as `command line arguments ` to C++ executables. +* Static remapping via `command line arguments `. +* Various improvements to the Python client library. +* Support for publishing and subscribing to serialized data. + This is the foundation for the upcoming work towards a native rosbag implementation. +* More `command line tools `\ , e.g. for working with parameters and lifecycle states. +* Binary packages / fat archives support three RMW implementations by default (without the need to build from source): + + * eProsima's FastRTPS (default) + * RTI's Connext + * ADLINK's OpenSplice + +For an overview of all features available, including those from earlier releases, please see the `Features ` page. + +Changes since the Ardent release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes since the `Ardent Apalone ` release: + + +* The Python package ``launch`` has been redesigned. + The previous Python API has been moved into a submodule ``launch.legacy``. + You can update existing launch files to continue to use the legacy API if a transition to the new Python API is not desired. +* The ROS topic names containing namespaces are mapped to DDS topics including their namespaces. + DDS partitions are not being used anymore for this. +* The recommended build tool is now ``colcon`` instead of ``ament_tools``. + This switch has no `implications `__ for the code in each ROS 2 package. + The install instructions have been updated and the `read-the-docs page `__ describes how to map an existing ``ament_tools`` call to ``colcon``. +* The argument order of `this rclcpp::Node::create_subscription() signature `__ has been modified. + +Known Issues +^^^^^^^^^^^^ + + +* New-style launch files `may hang on shutdown `__ for some combinations of platform and RMW implementation. +* Static remapping of namespaces `not working correctly `__ when addressed to a particular node. +* `Opensplice error messages may be printed `__ when using ``ros2 param`` and ``ros2 lifecycle`` command-line tools. diff --git a/Release-Howto.md b/Release-Howto.md deleted file mode 100644 index 944f3af9b1c..00000000000 --- a/Release-Howto.md +++ /dev/null @@ -1,63 +0,0 @@ -This page tries to capture the process we go through to make a new beta release of ROS 2. - -We usually don't branch before a release but "freeze" the used branch. -During the testing phase make sure that no unwanted changes are being committed to that branch. -Iteratively test either using the artifacts produced by the packaging jobs or from-source builds and make necessary changes. -Once the current state is ready to be released, follow these steps: - -- Get a fresh copy of all repositories using the master [`ros2.repos` file](https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos) - - `curl https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos | vcs import ./src` - -- Update the version number in (most) packages (excluding the ones which have their own numbering scheme). Also update the version numbers in all python packages that have a setup.py. - - Commit and push these changes: `vcs custom ./src --args commit -m "beta N" -a`, `vcs custom ./src --args push` - - -- Create a `.repos` file with the exact commit hashes you have checked out locally: - - `vcs export --exact ./src > hashes.repos` - -- Tag (most) repositories using `vcstool` - - For some repositories we are not creating ROS 2 specific tags but use the hashes instead: - - `ament/osrf_pycommon` - - `eProsima/Fast-CDR` - - `eProsima/Fast-RTPS` - - `ros/class_loader` - - `ros/console_bridge` - - Remove the above repositories for now: `rm -fr src/ament/osrf_pycommon src/eProsima src/ros` - - Note that for this step to work without requiring lots of password typing, you either need a `~/.netrc` file with your credentials, or you need to change the github URLs in the `.repos` file to use ssh instead of https. - - Create the release tag: - - `vcs custom ./src --args tag release-betaN` (adjust the tag name appropriately) - - If we ever have something other than `git` repositories we'll need to use the `--git` and `--hg` (for example) arguments separately. - - Update the `release-latest` tag on all repositories: - - `vcs custom ./src --args tag -f release-latest` - - Push tags (using force to overwrite existing latest tags): - - `vcs custom ./src --args push --tags -f` - -- Create new `.repos` file: - - `cp hashes.repos tags.repos` - - Edit `tags.repos` and replace the version attribute for all repositories (except the ones skipped before) with `release-betaN` (adjust the tag name appropriately) - -- Repeat the tagging and `.repos` file generation for the [`turtlebot2_demo.repos` file](https://github.com/ros2/turtlebot2_demo/blob/release-latest/turtlebot2_demo.repos) - - At beta3, only the turtlebot2_demo repo had packages that needed their version bumped, and no repos used a fixed hash instead of the release tag. - -- Run some packaging job using this new `.repos` file - - First upload `tags.repos` somewhere (e.g. gist.github.com). - - Then trigger a packaging job for each platform and use the url of the hosted `.repos` file in the `CI_ROS2_REPOS_URL` field. - - Rename each artifact file (an archive file) as `ros2-beta-package--.` - - E.g. `ros2-beta2-package-linux-fastrtps-x86_64.tar.bz2` - -- Create a tag on the `ros2/ros2` repository called `release-betaN` with the new `.repos` file: - - Clone `ros2/ros2` to the master branch. - - Replace the `ros2.repos` file's content with that of the `tags.repos` file created above. - - Commit it with a message like the tag name, e.g. `release-betaN` (adjust the tag name appropriately). - - Tag it with `git tag release-betaN` (adjust the tag name appropriately) and `git tag -f release-latest` push both with `git push --tags -f`. - -- Create a new release in the [Releases](https://github.com/ros2/ros2/releases) section of `ros2/ros2` using this new tag: - - Use the title `ROS 2 Beta N release` (matching the style of previous releases) -- Upload the renamed artifacts to the Release on GitHub using the web interface: - - E.g. https://github.com/ros2/ros2/releases/edit/release-beta2 -- Create an overview page for the beta release, e.g. https://github.com/ros2/ros2_documentation/Beta2-Overview -- Update the releases page to point to it: https://github.com/ros2/ros2_documentation/Releases -- Update the [Features page](https://github.com/ros2/ros2_documentation/Features.md) if appropriate -- Update the link on the home page: https://github.com/ros2/ros2_documentation/README.md -- [Run the documentation generation](https://github.com/ros2/docs.ros2.org/tree/doc_gen) and upload and link the results from http://docs.ros2.org/ -- Draft and send an announcement to discourse about that release diff --git a/Release-Howto.rst b/Release-Howto.rst new file mode 100644 index 00000000000..ef6d6b3349f --- /dev/null +++ b/Release-Howto.rst @@ -0,0 +1,103 @@ + +This page tries to capture the process we go through to make a new beta release of ROS 2. + +We usually don't branch before a release but "freeze" the used branch. +During the testing phase make sure that no unwanted changes are being committed to that branch. +Iteratively test either using the artifacts produced by the packaging jobs or from-source builds and make necessary changes. +Once the current state is ready to be released, follow these steps: + + +* + Get a fresh copy of all repositories using the master `\ ``ros2.repos`` file `__ + + + * ``curl https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos | vcs import ./src`` + +* + Update the version number in (most) packages (excluding the ones which have their own numbering scheme). Also update the version numbers in all python packages that have a setup.py. + + + * Commit and push these changes: ``vcs custom ./src --args commit -m "beta N" -a``\ , ``vcs custom ./src --args push`` + + +* + Create a ``.repos`` file with the exact commit hashes you have checked out locally: + + + * ``vcs export --exact ./src > hashes.repos`` + +* + Tag (most) repositories using ``vcstool`` + + + * For some repositories we are not creating ROS 2 specific tags but use the hashes instead: + + * ``ament/osrf_pycommon`` + * ``eProsima/Fast-CDR`` + * ``eProsima/Fast-RTPS`` + * ``ros/class_loader`` + * ``ros/console_bridge`` + * Remove the above repositories for now: ``rm -fr src/ament/osrf_pycommon src/eProsima src/ros`` + + * Note that for this step to work without requiring lots of password typing, you either need a ``~/.netrc`` file with your credentials, or you need to change the github URLs in the ``.repos`` file to use ssh instead of https. + * Create the release tag: + + * ``vcs custom ./src --args tag release-betaN`` (adjust the tag name appropriately) + * If we ever have something other than ``git`` repositories we'll need to use the ``--git`` and ``--hg`` (for example) arguments separately. + + * Update the ``release-latest`` tag on all repositories: + + * ``vcs custom ./src --args tag -f release-latest`` + + * Push tags (using force to overwrite existing latest tags): + + * ``vcs custom ./src --args push --tags -f`` + +* + Create new ``.repos`` file: + + + * ``cp hashes.repos tags.repos`` + * Edit ``tags.repos`` and replace the version attribute for all repositories (except the ones skipped before) with ``release-betaN`` (adjust the tag name appropriately) + +* + Repeat the tagging and ``.repos`` file generation for the `\ ``turtlebot2_demo.repos`` file `__ + + + * At beta3, only the turtlebot2_demo repo had packages that needed their version bumped, and no repos used a fixed hash instead of the release tag. + +* + Run some packaging job using this new ``.repos`` file + + + * First upload ``tags.repos`` somewhere (e.g. gist.github.com). + * Then trigger a packaging job for each platform and use the url of the hosted ``.repos`` file in the ``CI_ROS2_REPOS_URL`` field. + * Rename each artifact file (an archive file) as ``ros2-beta-package--.`` + + * E.g. ``ros2-beta2-package-linux-fastrtps-x86_64.tar.bz2`` + +* + Create a tag on the ``ros2/ros2`` repository called ``release-betaN`` with the new ``.repos`` file: + + + * Clone ``ros2/ros2`` to the master branch. + * Replace the ``ros2.repos`` file's content with that of the ``tags.repos`` file created above. + * Commit it with a message like the tag name, e.g. ``release-betaN`` (adjust the tag name appropriately). + * Tag it with ``git tag release-betaN`` (adjust the tag name appropriately) and ``git tag -f release-latest`` push both with ``git push --tags -f``. + +* + Create a new release in the `Releases `__ section of ``ros2/ros2`` using this new tag: + + + * Use the title ``ROS 2 Beta N release`` (matching the style of previous releases) + +* Upload the renamed artifacts to the Release on GitHub using the web interface: + + * E.g. https://github.com/ros2/ros2/releases/edit/release-beta2 + +* Create an overview page for the beta release, e.g. https://github.com/ros2/ros2_documentation/Beta2-Overview +* Update the releases page to point to it: https://github.com/ros2/ros2_documentation/Releases +* Update the `Features page `__ if appropriate +* Update the link on the home page: https://github.com/ros2/ros2_documentation/README +* `Run the documentation generation `__ and upload and link the results from http://docs.ros2.org/ +* Draft and send an announcement to discourse about that release diff --git a/Releases.md b/Releases.md deleted file mode 100644 index 600f7ffb12a..00000000000 --- a/Releases.md +++ /dev/null @@ -1,13 +0,0 @@ -A summary of releases of ROS 2 software is listed below. -For more details about each release, see the corresponding release overview. - -| Release Overview | Date | -| --- | --- | -| [Bouncy Bolson](Release-Bouncy-Bolson.md) | 2 July 2018 | -| [Ardent Apalone](Release-Ardent-Apalone.md) | 8 December 2017 | -| [beta3](Beta3-Overview.md) | 13 September 2017 | -| [beta2](Beta2-Overview.md) | 5 July 2017 | -| [beta1](Beta1-Overview.md) | 19 December 2016 | -| [alpha1-8](Alpha-Overview.md) | 31 August 2015 - 4 October 2016 | - -Notes on how a release is made: [Release-Howto](Release-Howto.md) diff --git a/Releases.rst b/Releases.rst new file mode 100644 index 00000000000..49c6579b790 --- /dev/null +++ b/Releases.rst @@ -0,0 +1,24 @@ + +A summary of releases of ROS 2 software is listed below. +For more details about each release, see the corresponding release overview. + +.. list-table:: + :header-rows: 1 + + * - Release Overview + - Date + * - `Bouncy Bolson ` + - 2 July 2018 + * - `Ardent Apalone ` + - 8 December 2017 + * - `beta3 ` + - 13 September 2017 + * - `beta2 ` + - 5 July 2017 + * - `beta1 ` + - 19 December 2016 + * - `alpha1-8 ` + - 31 August 2015 - 4 October 2016 + + +Notes on how a release is made: `Release-Howto ` diff --git a/Releasing-a-ROS-2-package-with-bloom.md b/Releasing-a-ROS-2-package-with-bloom.md deleted file mode 100644 index b042417ac3d..00000000000 --- a/Releasing-a-ROS-2-package-with-bloom.md +++ /dev/null @@ -1,35 +0,0 @@ -## Introduction - -This page describes how to prepare a repository for release on the public ROS 2 buildfarm. After you've created a package, this is the next step towards getting your package in to the publicly-available Debian packages (i.e., you will be able to install the package via `apt`). This page includes the ROS 2-specific instructions to execute before following the [Bloom release tutorial on the ROS Wiki](http://wiki.ros.org/bloom/Tutorials/FirstTimeRelease). - -### Required Tools - -For ROS 2 Bouncy: -* `bloom` >= 0.6.6 -* `catkin_pkg` >= 0.4.5 - -#### Ensure that you have the latest version of bloom and catkin_pkg - -See above version requirements. - -* Make sure you have the ros repositories in your sources (see [Instructions](Linux-Install-Debians.md#setup-sources)) - -* Install the latest version of bloom and catkin_pkg: -``` -sudo apt install python-catkin-pkg python-bloom -``` - -### Differences from ROS 1 Bloom - -If you've bloomed packages before in ROS 1, ROS 2's requirements will look familiar. - -ROS 2 uses a forked rosdistro index located at https://github.com/ros2/rosdistro. -You can configure bloom to use it by setting the `ROSDISTRO_INDEX_URL` environment variable. - -``` -export ROSDISTRO_INDEX_URL='https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml' -``` - -## Procedure - -Same as in ROS 1: [Following this tutorial]( http://wiki.ros.org/bloom/Tutorials/FirstTimeRelease.md) diff --git a/Releasing-a-ROS-2-package-with-bloom.rst b/Releasing-a-ROS-2-package-with-bloom.rst new file mode 100644 index 00000000000..268e6a1497d --- /dev/null +++ b/Releasing-a-ROS-2-package-with-bloom.rst @@ -0,0 +1,47 @@ + +Introduction +------------ + +This page describes how to prepare a repository for release on the public ROS 2 buildfarm. After you've created a package, this is the next step towards getting your package in to the publicly-available Debian packages (i.e., you will be able to install the package via ``apt``\ ). This page includes the ROS 2-specific instructions to execute before following the `Bloom release tutorial on the ROS Wiki `__. + +Required Tools +^^^^^^^^^^^^^^ + +For ROS 2 Bouncy: + + +* ``bloom`` >= 0.6.6 +* ``catkin_pkg`` >= 0.4.5 + +Ensure that you have the latest version of bloom and catkin_pkg +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See above version requirements. + + +* + Make sure you have the ros repositories in your sources (see `Instructions `\ ) + +* + Install the latest version of bloom and catkin_pkg: + + .. code-block:: + + sudo apt install python-catkin-pkg python-bloom + +Differences from ROS 1 Bloom +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you've bloomed packages before in ROS 1, ROS 2's requirements will look familiar. + +ROS 2 uses a forked rosdistro index located at https://github.com/ros2/rosdistro. +You can configure bloom to use it by setting the ``ROSDISTRO_INDEX_URL`` environment variable. + +.. code-block:: + + export ROSDISTRO_INDEX_URL='https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml' + +Procedure +--------- + +Same as in ROS 1: `Following this tutorial `__ diff --git a/Roadmap.md b/Roadmap.md deleted file mode 100644 index 8b0289c8a25..00000000000 --- a/Roadmap.md +++ /dev/null @@ -1,138 +0,0 @@ -# ROS 2 Roadmap - -For more information on the design of ROS 2 please see [design.ros2.org](http://design.ros2.org). -The core code for ROS 2 is on the [ros2 github organization](https://github.com/ros2). -The Discourse forum/mailing list for discussing ROS 2 design is [ng-ros](https://discourse.ros.org/c/ng-ros). -Questions should be asked on [ROS answers](https://answers.ros.org), make sure to include at least the `ros2` tag and the rosdistro version you are running, e.g. `ardent`. - -## Planned upcoming releases - -This is a list of the features targeted for development in the future. - -*Subject to change.* - -### Next release - Crystal Clemmys (December 2018) - -The [meta ticket](https://github.com/ros2/ros2/issues/529) on GitHub contains an up-to-date state of the ongoing high level tasks as well as references specific tickets with more details. - -- Support parameters in rclpy -- Time: support for simtime, clock / time in Python, rates / timers using specific clocks, using same clock in tf2 -- Port image_transport to ROS 2 -- Launch: support life cycle, support components, nesting, launch in containers, pass parameters -- Rosbag: record / playback binary messages, C++ API, Python CLI -- Port gazebo_ros_pkgs to ROS 2: the "main" plugins -- Port robot_web_tools -- Actions: code generation, server / client API -- IDL format: using `IDL 4.2` to specify ROS interfaces (msgs, srvs, actions), leverage new features like grouping and various annotations (comments, units) -- Improve MISRA compliance, audit memory management -- Buildfarm: keep non-latest .deb files, "incremental" CI job building of fat archive, CI jobs testing branches across repos, support nvidia-docker for testing with e.g. Gazebo -- Documentation infrastructure: rosindex-like page to browse/search metadata of ROS 2 packages, support generating docs from e.g. `.rst` files -- Performance testing - -### Future (in no specific order) - -#### Design / Concept - -- Support for non-ASCII strings in messages / services -- Progress on migration plan -- Reconsider 1-to-1 mapping of ROS nodes to DDS participants -- Python-based launch with stable API, introspectable, optional XML frontend -- Make `ament_cmake` available in ROS 1 and/or `catkin` available in ROS 2 - -#### Infrastructure and tools - -- Building - - Support to generate "fat" packages / archives - - Windows and Mac OS packages -- Documentation - - Platform for documentation (like wiki.ros.org), allow easy contributions as well as optionally facilitate a review process - - Support for `doc` jobs on the [ROS 2 buildfarm](http://build.ros2.org) - - Consider consolidating with design.ros2.org - - Provide three different kinds of content: - - "demos" to show features and cover them with tests - - "examples" to show a simple/minimalistic usage which might have multiple ways to do something - - "tutorials" which contain more comments and anchors for the wiki (teaching one recommended way) - -#### New features - -The trailing stars indicate the rough effort: 1 star for small, 2 stars for medium, 3 stars for large. - -- Expose matched publisher / subscriber count (rather than only based on the topic name) [**] - - E.g. a best effort publisher and a reliable subscriber, the current API returns 1 subscriber for the topic, so the publisher might do computational intensive work even though no subscriber needs the messages - - Querying this information requires a publisher / subscriber handle (against which the matched count is determined) - - Requires knowledge of the rmw interface which needs to be extended -- Logging improvements [* / **] - - Configuration specified in a file - - Log to file - - Log to `rosout` topic - - The API has a single callback at the moment, a composition callback could implement the multiple additional "destinations" - - Most of the implementation should be done in `rcl` - - C++ stream operators -- Additional Graph API features [** / ***] - - a la ROS 1 Master API: http://wiki.ros.org/ROS/Master_API - - Event-based notification - - Requires knowledge of the rmw interface which needs to be extended -- Remapping [** / ***] - - Dynamic remapping and aliasing through a Service interface -- Type masquerading [***] - - a la ROS 1's message traits: http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes - - Requires knowledge of the typesupport system -- Expand on real-time safety [***] - - With FastRTPS - - For services, clients, and parameters - - Support deterministic ordering of executables in Executor (fair scheduling) - - Expose more quality of service parameters related to real-time performance - - Real-time-safe intra-process messaging -- Multi-robot supporting features and demos [***] - - Undesired that all nodes across all robots share the same domain (and discover each other) - - Design how to “partition” the system -- Implement C client library `rclc` [**] -- Support more DDS / RTPS implementations: - - Connext dynamic [*] - - RTI's micro implementation [*] - - Eclipse Cyclone DDS (former ADLINK OpenSplice) [*] -- security improvements: - - more granularity in security configuration (allow authentication only, authentication and encryption, etc) [*] - - extend access control permission generation to support services [*] - - integrate DDS-Security logging plugin (unified way to aggregate security events and report them to the users through a ROS interface) [* *] - - key storage security (right now, keys are just stored in the filesystem) [* *] - - more user friendly interface (make it easier to specify security config). Maybe a Qt GUI? This GUI could also assist in distributing keys somehow. [* * *] - - A way to say "please secure this running system" with some UI that would auto-generate keys and policies for everything that is currently running. [* * *] - - If there are hardware-specific features for securing keys or accelerating encryption/signing messages, that could be interesting to add to DDS/RTPS implementations that don't use it already. [* * *] - -#### Port of existing ROS 1 functionality - -- Perception metapackage - - Image pipeline - - Improvements to the intra process comm. to reduce latency / overhead -- Navigation - - `robot_pose_ekf` or `robot_localization` - - `move_base` - - Working group https://discourse.ros.org/t/ros2-navigation-working-group-kick-off/5559 -- MoveIt - - Needs Actions - - Moveit Maintainers are tracking: https://discourse.ros.org/t/moveit-maintainer-meeting-recap-july-25th-2018/5504 -- Rqt - - `python_qt_binding` needs support for Python 3 (nothing ROS specific in this package) [*] - - `rqt_gui` / `rqt_gui_cpp` need to be migrated to use ROS 2 API [*] - - convert each plugin [* each when dependencies are available] - - User-friendly plugin registration -- Diagnostics - -#### Reducing Technical Debt - -- Extend testing and resolve bugs in the current code base - - Waitset inconsistency - - Multi-threading problems with components - - Reduce overhead / latency of intra-process communication -- Fix flaky tests. -- Ability to run (all) unit tests with tools e.g. valgrind -- API review -- Synchronize / reconcile design docs with the implementation. - - Pre-release retrospective review (APIs, docs, etc.) -- Address / classify pending tickets -- Address TODOs in code / docs - -## Past releases - -See [list of releases](Releases). diff --git a/Roadmap.rst b/Roadmap.rst new file mode 100644 index 00000000000..9157888875f --- /dev/null +++ b/Roadmap.rst @@ -0,0 +1,188 @@ + +ROS 2 Roadmap +============= + +For more information on the design of ROS 2 please see `design.ros2.org `__. +The core code for ROS 2 is on the `ros2 github organization `__. +The Discourse forum/mailing list for discussing ROS 2 design is `ng-ros `__. +Questions should be asked on `ROS answers `__\ , make sure to include at least the ``ros2`` tag and the rosdistro version you are running, e.g. ``ardent``. + +Planned upcoming releases +------------------------- + +This is a list of the features targeted for development in the future. + +*Subject to change.* + +Next release - Crystal Clemmys (December 2018) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The `meta ticket `__ on GitHub contains an up-to-date state of the ongoing high level tasks as well as references specific tickets with more details. + + +* Support parameters in rclpy +* Time: support for simtime, clock / time in Python, rates / timers using specific clocks, using same clock in tf2 +* Port image_transport to ROS 2 +* Launch: support life cycle, support components, nesting, launch in containers, pass parameters +* Rosbag: record / playback binary messages, C++ API, Python CLI +* Port gazebo_ros_pkgs to ROS 2: the "main" plugins +* Port robot_web_tools +* Actions: code generation, server / client API +* IDL format: using ``IDL 4.2`` to specify ROS interfaces (msgs, srvs, actions), leverage new features like grouping and various annotations (comments, units) +* Improve MISRA compliance, audit memory management +* Buildfarm: keep non-latest .deb files, "incremental" CI job building of fat archive, CI jobs testing branches across repos, support nvidia-docker for testing with e.g. Gazebo +* Documentation infrastructure: rosindex-like page to browse/search metadata of ROS 2 packages, support generating docs from e.g. ``.rst`` files +* Performance testing + +Future (in no specific order) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Design / Concept +~~~~~~~~~~~~~~~~ + + +* Support for non-ASCII strings in messages / services +* Progress on migration plan +* Reconsider 1-to-1 mapping of ROS nodes to DDS participants +* Python-based launch with stable API, introspectable, optional XML frontend +* Make ``ament_cmake`` available in ROS 1 and/or ``catkin`` available in ROS 2 + +Infrastructure and tools +~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Building + + * Support to generate "fat" packages / archives + * Windows and Mac OS packages + +* Documentation + + * Platform for documentation (like wiki.ros.org), allow easy contributions as well as optionally facilitate a review process + * Support for ``doc`` jobs on the `ROS 2 buildfarm `__ + * Consider consolidating with design.ros2.org + * Provide three different kinds of content: + + * "demos" to show features and cover them with tests + * "examples" to show a simple/minimalistic usage which might have multiple ways to do something + * "tutorials" which contain more comments and anchors for the wiki (teaching one recommended way) + +New features +~~~~~~~~~~~~ + +The trailing stars indicate the rough effort: 1 star for small, 2 stars for medium, 3 stars for large. + + +* Expose matched publisher / subscriber count (rather than only based on the topic name) [**] + + * E.g. a best effort publisher and a reliable subscriber, the current API returns 1 subscriber for the topic, so the publisher might do computational intensive work even though no subscriber needs the messages + * Querying this information requires a publisher / subscriber handle (against which the matched count is determined) + * Requires knowledge of the rmw interface which needs to be extended + +* Logging improvements [* / **] + + * Configuration specified in a file + * Log to file + * Log to ``rosout`` topic + * The API has a single callback at the moment, a composition callback could implement the multiple additional "destinations" + * Most of the implementation should be done in ``rcl`` + * C++ stream operators + +* Additional Graph API features [\ ** / ***\ ] + + * a la ROS 1 Master API: http://wiki.ros.org/ROS/Master_API + * Event-based notification + * Requires knowledge of the rmw interface which needs to be extended + +* Remapping [\ ** / ***\ ] + + * Dynamic remapping and aliasing through a Service interface + +* Type masquerading [***] + + * a la ROS 1's message traits: http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes + * Requires knowledge of the typesupport system + +* Expand on real-time safety [***] + + * With FastRTPS + * For services, clients, and parameters + * Support deterministic ordering of executables in Executor (fair scheduling) + * Expose more quality of service parameters related to real-time performance + * Real-time-safe intra-process messaging + +* Multi-robot supporting features and demos [***] + + * Undesired that all nodes across all robots share the same domain (and discover each other) + * Design how to “partition” the system + +* Implement C client library ``rclc`` [**] +* Support more DDS / RTPS implementations: + + * Connext dynamic [*] + * RTI's micro implementation [*] + * Eclipse Cyclone DDS (former ADLINK OpenSplice) [*] + +* security improvements: + + * more granularity in security configuration (allow authentication only, authentication and encryption, etc) [*] + * extend access control permission generation to support services [*] + * integrate DDS-Security logging plugin (unified way to aggregate security events and report them to the users through a ROS interface) [\ * *\ ] + * key storage security (right now, keys are just stored in the filesystem) [\ * *\ ] + * more user friendly interface (make it easier to specify security config). Maybe a Qt GUI? This GUI could also assist in distributing keys somehow. [\ * * *] + * A way to say "please secure this running system" with some UI that would auto-generate keys and policies for everything that is currently running. [\ * * *] + * If there are hardware-specific features for securing keys or accelerating encryption/signing messages, that could be interesting to add to DDS/RTPS implementations that don't use it already. [\ * * *] + +Port of existing ROS 1 functionality +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* Perception metapackage + + * Image pipeline + * Improvements to the intra process comm. to reduce latency / overhead + +* Navigation + + * ``robot_pose_ekf`` or ``robot_localization`` + * ``move_base`` + * Working group https://discourse.ros.org/t/ros2-navigation-working-group-kick-off/5559 + +* MoveIt + + * Needs Actions + * Moveit Maintainers are tracking: https://discourse.ros.org/t/moveit-maintainer-meeting-recap-july-25th-2018/5504 + +* Rqt + + * ``python_qt_binding`` needs support for Python 3 (nothing ROS specific in this package) [*] + * ``rqt_gui`` / ``rqt_gui_cpp`` need to be migrated to use ROS 2 API [*] + * convert each plugin [* each when dependencies are available] + * User-friendly plugin registration + +* Diagnostics + +Reducing Technical Debt +~~~~~~~~~~~~~~~~~~~~~~~ + + +* Extend testing and resolve bugs in the current code base + + * Waitset inconsistency + * Multi-threading problems with components + * Reduce overhead / latency of intra-process communication + +* Fix flaky tests. +* Ability to run (all) unit tests with tools e.g. valgrind +* API review +* Synchronize / reconcile design docs with the implementation. + + * Pre-release retrospective review (APIs, docs, etc.) + +* Address / classify pending tickets +* Address TODOs in code / docs + +Past releases +------------- + +See `list of releases `. diff --git a/Rosbag-with-ROS1-Bridge.md b/Rosbag-with-ROS1-Bridge.md deleted file mode 100644 index 9d601ce3902..00000000000 --- a/Rosbag-with-ROS1-Bridge.md +++ /dev/null @@ -1,221 +0,0 @@ -# Rosbag with ROS1 Bridge - -This tutorial is a follow up to the "Bridge communication between ROS 1 and ROS 2" tutorial linked to from the [Tutorials page on this wiki](Tutorials), and this tutorial assumes you have completed that tutorial already. - -The ros1_bridge can either be installed from [packages](Installation.md) or [built from source](https://github.com/ros2/ros1_bridge/blob/master/README.md#building-the-bridge-from-source); both work for these examples. - -What follows is a series of additional examples, like that ones that come at the end of the aforementioned "Bridge communication between ROS 1 and ROS 2" tutorial. - -## Recording Topic Data with rosbag and ROS 1 Bridge - -In this example, we'll be using the `cam2image` demo program that comes with ROS 2 and a Python script to emulate a simple turtlebot-like robot's sensor data so that we can bridge it to ROS 1 and use rosbag to record it. - -First we'll run a ROS 1 `roscore` in a new shell: - -``` -# Shell A: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -roscore -``` - -Then we'll run the ROS 1 <=> ROS 2 `dynamic_bridge` with the `--bridge-all-topics` option (so we can do `rostopic list` and see them) in another shell: - -``` -# Shell B: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -. /opt/ros/ardent/setup.bash -# Or, if building ROS2 from source: -# . /install/setup.bash -export ROS_MASTER_URI=http://localhost:11311 -ros2 run ros1_bridge dynamic_bridge --bridge-all-topics -``` - -Remember to replace `` with the path to where you either extracted the ROS 2 binary or where you built ROS 2 from source. - ---- - -Now we can start up the ROS 2 programs that will emulate our turtlebot-like robot. -First we'll run the `cam2image` program with the `-b` option so it doesn't require a camera to work: - -``` -# Shell C: -. /opt/ros/ardent/setup.bash -# Or, if building ROS2 from source: -# . /install/setup.bash -ros2 run image_tools cam2image -- -b -``` - -TODO: use namespaced topic names - -Then we'll run a simple Python script to emulate the `odom` and `imu_data` topics from a Kobuki base. -I would use the more accurate `~sensors/imu_data` topic name for the imu data, but we don't have namespace support just yet in ROS 2 (it's coming!). -Place this script in a file called `emulate_kobuki_node.py`: - -```python -#!/usr/bin/env python3 - -import sys -import time - -import rclpy - -from nav_msgs.msg import Odometry -from sensor_msgs.msg import Imu - -def main(): - rclpy.init(args=sys.argv) - - node = rclpy.create_node('emulate_kobuki_node') - - imu_publisher = node.create_publisher(Imu, 'imu_data') - odom_publisher = node.create_publisher(Odometry, 'odom') - - imu_msg = Imu() - odom_msg = Odometry() - counter = 0 - while True: - counter += 1 - now = time.time() - if (counter % 50) == 0: - odom_msg.header.stamp.sec = int(now) - odom_msg.header.stamp.nanosec = int(now * 1e9) % 1000000000 - odom_publisher.publish(odom_msg) - if (counter % 100) == 0: - imu_msg.header.stamp.sec = int(now) - imu_msg.header.stamp.nanosec = int(now * 1e9) % 1000000000 - imu_publisher.publish(imu_msg) - counter = 0 - time.sleep(0.001) - - -if __name__ == '__main__': - sys.exit(main()) - -``` - -You can run this python script in a new ROS 2 shell: - -``` -# Shell D: -. /opt/ros/ardent/setup.bash -# Or, if building ROS2 from source: -# . /install/setup.bash -python3 emulate_kobuki_node.py -``` - ---- - -Now that all the data sources and the dynamic bridge are running, we can look at the available topics in a new ROS 1 shell: - -``` -# Shell E: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -rostopic list -``` - -You should see something like this: - -``` -% rostopic list -/image -/imu_data -/odom -/rosout -/rosout_agg -``` - -We can now record this data with `rosbag record` in the same shell: - -``` -# Shell E: -rosbag record /image /imu_data /odom -``` - -After a few seconds you can `Ctrl-c` the `rosbag` command and do an `ls -lh` to see how big the file is, you might see something like this: - -``` -% ls -lh -total 0 --rw-rw-r-- 1 william william 12M Feb 23 16:59 2017-02-23-16-59-47.bag -``` - -Though the file name will be different for your bag (since it is derived from the date and time). - -## Playing Back Topic Data with rosbag and ROS 1 Bridge - -Now that we have a bag file you can use any of the ROS 1 tools to introspect the bag file, like `rosbag info `, `rostopic list -b `, or `rqt_bag `. -However, we can also playback bag data into ROS 2 using `rosbag play` and the ROS 1 <=> ROS 2 `dynamic_bridge`. - -First close out all the shells you opened for the previous tutorial, stopping any running programs. - -Then in a new shell start the `roscore`: - -``` -# Shell P: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -roscore -``` - -Then run the `dynamic_bridge` in another shell: - -``` -# Shell Q: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -. /opt/ros/ardent/setup.bash -# Or, if building ROS2 from source: -# . /install/setup.bash -export ROS_MASTER_URI=http://localhost:11311 -ros2 run ros1_bridge dynamic_bridge --bridge-all-topics -``` - -Then play the bag data back with `rosbag play` in another new shell, using the `--loop` option so that we don't have to keep restarting it for short bags: - -``` -# Shell R: -. /opt/ros/kinetic/setup.bash -# Or, on OSX, something like: -# . ~/ros_catkin_ws/install_isolated/setup.bash -rosbag play --loop path/to/bag_file -``` - -Make sure to replace `path/to/bag_file` with the path to the bag file you want to playback. - ---- - -Now that the data is being played back and the bridge is running we can see the data coming across in ROS 2. - -``` -# Shell S: -. /opt/ros/ardent/setup.bash -# Or, if building ROS2 from source: -# . /install/setup.bash -ros2 topic list -ros2 topic echo /odom -``` - -You should see something like: - -``` -% ros2 topic list -/clock -/image -/imu_data -/odom -/parameter_events -``` - -You can also see the image being played from the bag by using the `showimage` tool: - -``` -% ros2 run image_tools showimage -``` \ No newline at end of file diff --git a/Rosbag-with-ROS1-Bridge.rst b/Rosbag-with-ROS1-Bridge.rst new file mode 100644 index 00000000000..7346717b04f --- /dev/null +++ b/Rosbag-with-ROS1-Bridge.rst @@ -0,0 +1,224 @@ + +Rosbag with ROS1 Bridge +======================= + +This tutorial is a follow up to the "Bridge communication between ROS 1 and ROS 2" tutorial linked to from the `Tutorials page on this wiki `\ , and this tutorial assumes you have completed that tutorial already. + +The ros1_bridge can either be installed from `packages ` or `built from source `__\ ; both work for these examples. + +What follows is a series of additional examples, like that ones that come at the end of the aforementioned "Bridge communication between ROS 1 and ROS 2" tutorial. + +Recording Topic Data with rosbag and ROS 1 Bridge +------------------------------------------------- + +In this example, we'll be using the ``cam2image`` demo program that comes with ROS 2 and a Python script to emulate a simple turtlebot-like robot's sensor data so that we can bridge it to ROS 1 and use rosbag to record it. + +First we'll run a ROS 1 ``roscore`` in a new shell: + +.. code-block:: + + # Shell A: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + roscore + +Then we'll run the ROS 1 <=> ROS 2 ``dynamic_bridge`` with the ``--bridge-all-topics`` option (so we can do ``rostopic list`` and see them) in another shell: + +.. code-block:: + + # Shell B: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + . /opt/ros/ardent/setup.bash + # Or, if building ROS2 from source: + # . /install/setup.bash + export ROS_MASTER_URI=http://localhost:11311 + ros2 run ros1_bridge dynamic_bridge --bridge-all-topics + +Remember to replace ```` with the path to where you either extracted the ROS 2 binary or where you built ROS 2 from source. + +---- + +Now we can start up the ROS 2 programs that will emulate our turtlebot-like robot. +First we'll run the ``cam2image`` program with the ``-b`` option so it doesn't require a camera to work: + +.. code-block:: + + # Shell C: + . /opt/ros/ardent/setup.bash + # Or, if building ROS2 from source: + # . /install/setup.bash + ros2 run image_tools cam2image -- -b + +TODO: use namespaced topic names + +Then we'll run a simple Python script to emulate the ``odom`` and ``imu_data`` topics from a Kobuki base. +I would use the more accurate ``~sensors/imu_data`` topic name for the imu data, but we don't have namespace support just yet in ROS 2 (it's coming!). +Place this script in a file called ``emulate_kobuki_node.py``\ : + +.. code-block:: python + + #!/usr/bin/env python3 + + import sys + import time + + import rclpy + + from nav_msgs.msg import Odometry + from sensor_msgs.msg import Imu + + def main(): + rclpy.init(args=sys.argv) + + node = rclpy.create_node('emulate_kobuki_node') + + imu_publisher = node.create_publisher(Imu, 'imu_data') + odom_publisher = node.create_publisher(Odometry, 'odom') + + imu_msg = Imu() + odom_msg = Odometry() + counter = 0 + while True: + counter += 1 + now = time.time() + if (counter % 50) == 0: + odom_msg.header.stamp.sec = int(now) + odom_msg.header.stamp.nanosec = int(now * 1e9) % 1000000000 + odom_publisher.publish(odom_msg) + if (counter % 100) == 0: + imu_msg.header.stamp.sec = int(now) + imu_msg.header.stamp.nanosec = int(now * 1e9) % 1000000000 + imu_publisher.publish(imu_msg) + counter = 0 + time.sleep(0.001) + + + if __name__ == '__main__': + sys.exit(main()) + +You can run this python script in a new ROS 2 shell: + +.. code-block:: + + # Shell D: + . /opt/ros/ardent/setup.bash + # Or, if building ROS2 from source: + # . /install/setup.bash + python3 emulate_kobuki_node.py + +---- + +Now that all the data sources and the dynamic bridge are running, we can look at the available topics in a new ROS 1 shell: + +.. code-block:: + + # Shell E: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + rostopic list + +You should see something like this: + +.. code-block:: + + % rostopic list + /image + /imu_data + /odom + /rosout + /rosout_agg + +We can now record this data with ``rosbag record`` in the same shell: + +.. code-block:: + + # Shell E: + rosbag record /image /imu_data /odom + +After a few seconds you can ``Ctrl-c`` the ``rosbag`` command and do an ``ls -lh`` to see how big the file is, you might see something like this: + +.. code-block:: + + % ls -lh + total 0 + -rw-rw-r-- 1 william william 12M Feb 23 16:59 2017-02-23-16-59-47.bag + +Though the file name will be different for your bag (since it is derived from the date and time). + +Playing Back Topic Data with rosbag and ROS 1 Bridge +---------------------------------------------------- + +Now that we have a bag file you can use any of the ROS 1 tools to introspect the bag file, like ``rosbag info ``\ , ``rostopic list -b ``\ , or ``rqt_bag ``. +However, we can also playback bag data into ROS 2 using ``rosbag play`` and the ROS 1 <=> ROS 2 ``dynamic_bridge``. + +First close out all the shells you opened for the previous tutorial, stopping any running programs. + +Then in a new shell start the ``roscore``\ : + +.. code-block:: + + # Shell P: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + roscore + +Then run the ``dynamic_bridge`` in another shell: + +.. code-block:: + + # Shell Q: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + . /opt/ros/ardent/setup.bash + # Or, if building ROS2 from source: + # . /install/setup.bash + export ROS_MASTER_URI=http://localhost:11311 + ros2 run ros1_bridge dynamic_bridge --bridge-all-topics + +Then play the bag data back with ``rosbag play`` in another new shell, using the ``--loop`` option so that we don't have to keep restarting it for short bags: + +.. code-block:: + + # Shell R: + . /opt/ros/kinetic/setup.bash + # Or, on OSX, something like: + # . ~/ros_catkin_ws/install_isolated/setup.bash + rosbag play --loop path/to/bag_file + +Make sure to replace ``path/to/bag_file`` with the path to the bag file you want to playback. + +---- + +Now that the data is being played back and the bridge is running we can see the data coming across in ROS 2. + +.. code-block:: + + # Shell S: + . /opt/ros/ardent/setup.bash + # Or, if building ROS2 from source: + # . /install/setup.bash + ros2 topic list + ros2 topic echo /odom + +You should see something like: + +.. code-block:: + + % ros2 topic list + /clock + /image + /imu_data + /odom + /parameter_events + +You can also see the image being played from the bag by using the ``showimage`` tool: + +.. code-block:: + + % ros2 run image_tools showimage diff --git a/Rosidl-Tutorial.md b/Rosidl-Tutorial.md deleted file mode 100644 index fe1bc9af0da..00000000000 --- a/Rosidl-Tutorial.md +++ /dev/null @@ -1,476 +0,0 @@ -**INCOMPLETE: this is a draft of an upcoming tutorial for creating and using custom ROS interfaces.** - -**Disclaimer: The code provided is to support the explanation, it is likely outdated and should not be expected to compile as is** - -# Introduction to msg and srv - -* msg: msg files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages. -* srv: an srv file describes a service. It is composed of two parts: a request and a response. The request and response are message declarations. - -msgs are just simple text files with a field type and field name per line. The field types you can use are: - -* int8, int16, int32, int64 (plus uint*) -* float32, float64 -* string -* other msg files -* variable-length array[], fixed-length array[C], bounded-length array[<=C] - - -Here is an example of a msg that uses a string primitive, and two other msgs: -``` - string child_frame_id - geometry_msgs/PoseWithCovariance pose - geometry_msgs/TwistWithCovariance twist -``` - -srv files are just like msg files, except they contain two parts: a request and a response. The two parts are separated by a '---' line. Here is an example of a srv file: - -``` -float64 A -float64 B ---- -float64 Sum -``` -In the above example, A and B are the request, and Sum is the response. - -msg files are stored in the `msg` directory of a package, and srv files are stored in the `srv` directory. - -These are just simple examples. -For more information about how to create msg and srv files please refer to [About ROS Interfaces](About-ROS-Interfaces.md). - -# Creating a msg package - -**NOTE:** only ament_cmake packages can generate messages currently (not ament_python packages). - -For this tutorial we will use the packages stored in the [rosidl_tutorials repository](https://github.com/ros2/tutorials/tree/rosidl_tutorials/rosidl_tutorials) -``` -cd ~/ros2_overlway_ws/src -git clone -b rosidl_tutorials https://github.com/ros2/tutorials.git -cd rosidl_tutorials/rosidl_tutorials_msgs -``` -## Creating a msg file -Here we will create a message meant to carry information about an individual. - -Open `msg/Contact.msg` and you will see: - -``` -bool FEMALE=true -bool MALE=false - -string first_name -string last_name -bool gender -uint8 age -string address -``` - -This message is composed of 5 fields: -- first_name: of type string -- last_name: of type string -- gender: of type bool, that can be either MALE or FEMALE -- age: of type uint8 -- address: of type string - -There's one more step, though. We need to make sure that the msg files are turned into source code for C++, Python, and other languages: - -Open the `package.xml`, and uncomment these two lines: -```xml - rosidl_default_generators - - rosidl_default_runtime -``` - -Note that at build time, we need "rosidl_default_generators", while at runtime, we only need "rosidl_default_runtime". - -Open the `CMakeLists.txt` and make sure that the following lines are uncommented. - -Find the package that generates message code from msg/srv files: -```cmake -find_package(rosidl_default_generators REQUIRED) -``` - -Declare the list of messages you want to generate: -```cmake -set(msg_files - "msg/Contact.msg" -) -``` - -By adding the .msg files manually, we make sure that CMake knows when it has to reconfigure the project after you add other .msg files. - -Generate the messages: -```cmake -rosidl_generate_interfaces(${PROJECT_NAME} - ${msg_files} -) -``` - -Also make sure you export the message runtime dependency: -```cmake -ament_export_dependencies(rosidl_default_runtime) -``` - - -Now you're ready to generate source files from your msg definition. - -# Creating a srv - -We will now add a srv declaration to our package. - -Open the srv/AddTwoFloats.srv file and paste this srv declaration: - -``` -float64 a -float64 b ---- -float64 sum - -``` - -Declare the service in the `CMakeLists.txt`: -```cmake -set(srv_files - "srv/AddTwoFloats.srv") -``` - -Modify the existing call to rosidl_generate_interfaces to generate the service in addition to the messages: -```cmake -rosidl_generate_interfaces(${PROJECT_NAME} - ${msg_files} - ${srv_files} -) -``` - -# Using custom messages -## Using msg/srv from other packages -Let's write a C++ node using the Contact.msg we just created. - -Go to the rosidl_tutorials package and open the src/publish_contact.cpp file. -```c++ -#include -#include - -#include "rclcpp/rclcpp.hpp" - -#include "rosidl_tutorials_msgs/msg/contact.hpp" - - -using namespace std::chrono_literals; - -class ContactPublisher : public rclcpp::Node -{ -public: - ContactPublisher() - : Node("address_book_publisher") - { - contact_publisher_ = this->create_publisher("contact"); - - auto publish_msg = [this]() -> void { - auto msg = std::make_shared(); - - msg->first_name = "John"; - msg->last_name = "Doe"; - msg->age = 30; - msg->gender = msg->MALE; - msg->address = "unknown"; - - std::cout << "Publishing Contact\nFirst:" << msg->first_name << - " Last:" << msg->last_name << std::endl; - - contact_publisher_->publish(msg); - }; - timer_ = this->create_wall_timer(1s, publish_msg); - } - -private: - rclcpp::Publisher::SharedPtr contact_publisher_; - rclcpp::timer::TimerBase::SharedPtr timer_; -}; - - -int main(int argc, char * argv[]) -{ - rclcpp::init(argc, argv); - - auto publisher_node = std::make_shared(); - - rclcpp::spin(publisher_node); - - return 0; -} -``` -### The code explained -```c++ -#include "rosidl_tutorials_msgs/msg/contact.hpp" -``` -Here we include the header of the message that we want to use. - -```c++ - ContactPublisher() - : Node("address_book_publisher") - { -``` -Here we define a node - -```c++ -auto publish_msg = [this]() -> void { - -``` -A publish_msg function to send our message periodically - -```c++ - auto msg = std::make_shared(); - - msg->first_name = "John"; - msg->last_name = "Doe"; - msg->age = 30; - msg->gender = msg->MALE; - msg->address = "unknown"; -``` -We create a Contact message and populate its fields. - -```c++ - std::cout << "Publishing Contact\nFirst:" << msg->first_name << - " Last:" << msg->last_name << std::endl; - - contact_publisher_->publish(msg); -``` -Finally we publish it - -```c++ - timer_ = this->create_wall_timer(1s, publish_msg); -``` -Create a 1second timer to call our `publish_msg` function every second - -Now let's build it! - -To use this message we need to declare a dependency on rosidl_tutorials_msgs in the `package.xml`: -```xml - rosidl_tutorials_msgs - - rosidl_tutorials_msgs -``` - -And also in the `CMakeLists.txt`: -```cmake -find_package(rosidl_tutorials_msgs REQUIRED) - -``` - -And finally we must declare the message package as a target dependency for the executable. -```cmake -ament_target_dependencies(publish_contact - "rclcpp" - "rosidl_tutorials_msgs" -) -``` - - -## Using msg/srv from the same package -While most of the time messages are declared in interface packages, it can be convenient to declare, create and use messages all in the one package. - -We will create a message in our rosidl_tutorials package. -Create a msg directory in the rosidl_tutorials package and AddressBook.msg inside that directory. -In that msg paste: -``` -rosidl_tutorials_msgs/Contact[] address_book -``` - -As you can see we define a message based on the Contact message we created earlier. - -To generate this message we need to declare a dependency on this package in the `package.xml`: -```xml - rosidl_tutorials_msgs - - rosidl_tutorials_msgs -``` - -And in the `CMakeLists.txt`: -```cmake -find_package(rosidl_tutorials_msgs REQUIRED) - -set(msg_files - "msg/AddressBook.msg" -) - -rosidl_generate_interfaces(${PROJECT_NAME} - ${msg_files} - DEPENDENCIES rosidl_tutorials_msgs -) -``` - -Now we can start writing code that uses this message. - -Open src/publish_address_book.cpp: - -```c++ -#include -#include - -#include "rclcpp/rclcpp.hpp" - -#include "rosidl_tutorials/msg/address_book.hpp" -#include "rosidl_tutorials_msgs/msg/contact.hpp" - -using namespace std::chrono_literals; - -class AddressBookPublisher : public rclcpp::Node -{ -public: - AddressBookPublisher() - : Node("address_book_publisher") - { - address_book_publisher_ = - this->create_publisher("address_book"); - - auto publish_msg = [this]() -> void { - auto msg = std::make_shared(); - { - rosidl_tutorials_msgs::msg::Contact contact; - contact.first_name = "John"; - contact.last_name = "Doe"; - contact.age = 30; - contact.gender = contact.MALE; - contact.address = "unknown"; - msg->address_book.push_back(contact); - } - { - rosidl_tutorials_msgs::msg::Contact contact; - contact.first_name = "Jane"; - contact.last_name = "Doe"; - contact.age = 20; - contact.gender = contact.FEMALE; - contact.address = "unknown"; - msg->address_book.push_back(contact); - } - - std::cout << "Publishing address book:" << std::endl; - for (auto contact : msg->address_book) { - std::cout << "First:" << contact.first_name << " Last:" << contact.last_name << - std::endl; - } - - address_book_publisher_->publish(msg); - }; - timer_ = this->create_wall_timer(1s, publish_msg); - } - -private: - rclcpp::Publisher::SharedPtr address_book_publisher_; - rclcpp::timer::TimerBase::SharedPtr timer_; -}; - - -int main(int argc, char * argv[]) -{ - rclcpp::init(argc, argv); - auto publisher_node = std::make_shared(); - - rclcpp::spin(publisher_node); - - return 0; -} -``` - -### The code explained -```c++ -#include "rosidl_tutorials/msg/address_book.hpp" -``` -We include the header of our newly created AddressBook msg. -```c++ -#include "rosidl_tutorials_msgs/msg/contact.hpp" -``` -Here we include the header of the Contact msg in order to be able to add contacts to our address_book. - -```c++ -using namespace std::chrono_literals; - -class AddressBookPublisher : public rclcpp::Node -{ -public: - AddressBookPublisher() - : Node("address_book_publisher") - { - address_book_publisher_ = - this->create_publisher("address_book"); - -``` -We create a node and an AddressBook publisher. -```c++ - auto publish_msg = [this]() -> void { -``` -We create a callback to publish the messages periodically - -```c++ - auto msg = std::make_shared(); -``` -We create an AddressBook message instance that we will later publish. - -```c++ - { - rosidl_tutorials_msgs::msg::Contact contact; - contact.first_name = "John"; - contact.last_name = "Doe"; - contact.age = 30; - contact.gender = contact.MALE; - contact.address = "unknown"; - msg->address_book.push_back(person); - } - { - rosidl_tutorials_msgs::msg::Contact person; - contact.first_name = "Jane"; - contact.last_name = "Doe"; - contact.age = 20; - contact.gender = contact.FEMALE; - contact.address = "unknown"; - msg->address_book.push_back(contact); - } -``` -We create and populate Contact messages and add them to our address_book message. -```c++ - std::cout << "Publishing address book:" << std::endl; - for (auto contact : msg->address_book) { - std::cout << "First:" << contact.first_name << " Last:" << contact.last_name << - std::endl; - } - - address_book_publisher_->publish(msg); -``` -Finally send the message periodically. - -```c++ - timer_ = this->create_wall_timer(1s, publish_msg); -``` -Create a 1second timer to call our `publish_msg` function every second - -Now let's build it! -We need to create a new target for this node in the `CMakeLists.txt`: -```cmake -add_executable(publish_address_book - src/publish_address_book.cpp -) - -ament_target_dependencies(publish_address_book - "rclcpp" -) -``` - - -In order to use the messages generated in the same package we need to use the following cmake code: - -```cmake -get_default_rmw_implementation(rmw_implementation) -find_package("${rmw_implementation}" REQUIRED) -get_rmw_typesupport(typesupport_impls "${rmw_implementation}" LANGUAGE "cpp") - -foreach(typesupport_impl ${typesupport_impls}) - rosidl_target_interfaces(publish_address_book - ${PROJECT_NAME} ${typesupport_impl} - ) -endforeach() -``` -This finds the relevant generated C++ code from msg/srv and allows your target to link against them. - -You may have noticed that this step was not necessary when the interfaces being used were from a package that was built beforehand. -This CMake code is only required when you are trying to use interfaces in the same package as that in which they are built. - diff --git a/Rosidl-Tutorial.rst b/Rosidl-Tutorial.rst new file mode 100644 index 00000000000..d2269193731 --- /dev/null +++ b/Rosidl-Tutorial.rst @@ -0,0 +1,525 @@ + +**INCOMPLETE: this is a draft of an upcoming tutorial for creating and using custom ROS interfaces.** + +**Disclaimer: The code provided is to support the explanation, it is likely outdated and should not be expected to compile as is** + +Introduction to msg and srv +=========================== + + +* msg: msg files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages. +* srv: an srv file describes a service. It is composed of two parts: a request and a response. The request and response are message declarations. + +msgs are just simple text files with a field type and field name per line. The field types you can use are: + + +* int8, int16, int32, int64 (plus uint*) +* float32, float64 +* string +* other msg files +* variable-length array[], fixed-length array[C], bounded-length array[<=C] + +Here is an example of a msg that uses a string primitive, and two other msgs: + +.. code-block:: + + string child_frame_id + geometry_msgs/PoseWithCovariance pose + geometry_msgs/TwistWithCovariance twist + +srv files are just like msg files, except they contain two parts: a request and a response. The two parts are separated by a '---' line. Here is an example of a srv file: + +.. code-block:: + + float64 A + float64 B + --- + float64 Sum + +In the above example, A and B are the request, and Sum is the response. + +msg files are stored in the ``msg`` directory of a package, and srv files are stored in the ``srv`` directory. + +These are just simple examples. +For more information about how to create msg and srv files please refer to `About ROS Interfaces `. + +Creating a msg package +====================== + +**NOTE:** only ament_cmake packages can generate messages currently (not ament_python packages). + +For this tutorial we will use the packages stored in the `rosidl_tutorials repository `__ + +.. code-block:: + + cd ~/ros2_overlway_ws/src + git clone -b rosidl_tutorials https://github.com/ros2/tutorials.git + cd rosidl_tutorials/rosidl_tutorials_msgs + +Creating a msg file +------------------- + +Here we will create a message meant to carry information about an individual. + +Open ``msg/Contact.msg`` and you will see: + +.. code-block:: + + bool FEMALE=true + bool MALE=false + + string first_name + string last_name + bool gender + uint8 age + string address + +This message is composed of 5 fields: + + +* first_name: of type string +* last_name: of type string +* gender: of type bool, that can be either MALE or FEMALE +* age: of type uint8 +* address: of type string + +There's one more step, though. We need to make sure that the msg files are turned into source code for C++, Python, and other languages: + +Open the ``package.xml``\ , and uncomment these two lines: + +.. code-block:: xml + + rosidl_default_generators + + rosidl_default_runtime + +Note that at build time, we need "rosidl_default_generators", while at runtime, we only need "rosidl_default_runtime". + +Open the ``CMakeLists.txt`` and make sure that the following lines are uncommented. + +Find the package that generates message code from msg/srv files: + +.. code-block:: cmake + + find_package(rosidl_default_generators REQUIRED) + +Declare the list of messages you want to generate: + +.. code-block:: cmake + + set(msg_files + "msg/Contact.msg" + ) + +By adding the .msg files manually, we make sure that CMake knows when it has to reconfigure the project after you add other .msg files. + +Generate the messages: + +.. code-block:: cmake + + rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + ) + +Also make sure you export the message runtime dependency: + +.. code-block:: cmake + + ament_export_dependencies(rosidl_default_runtime) + +Now you're ready to generate source files from your msg definition. + +Creating a srv +============== + +We will now add a srv declaration to our package. + +Open the srv/AddTwoFloats.srv file and paste this srv declaration: + +.. code-block:: + + float64 a + float64 b + --- + float64 sum + +Declare the service in the ``CMakeLists.txt``\ : + +.. code-block:: cmake + + set(srv_files + "srv/AddTwoFloats.srv") + +Modify the existing call to rosidl_generate_interfaces to generate the service in addition to the messages: + +.. code-block:: cmake + + rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + ${srv_files} + ) + +Using custom messages +===================== + +Using msg/srv from other packages +--------------------------------- + +Let's write a C++ node using the Contact.msg we just created. + +Go to the rosidl_tutorials package and open the src/publish_contact.cpp file. + +.. code-block:: c++ + + #include + #include + + #include "rclcpp/rclcpp.hpp" + + #include "rosidl_tutorials_msgs/msg/contact.hpp" + + + using namespace std::chrono_literals; + + class ContactPublisher : public rclcpp::Node + { + public: + ContactPublisher() + : Node("address_book_publisher") + { + contact_publisher_ = this->create_publisher("contact"); + + auto publish_msg = [this]() -> void { + auto msg = std::make_shared(); + + msg->first_name = "John"; + msg->last_name = "Doe"; + msg->age = 30; + msg->gender = msg->MALE; + msg->address = "unknown"; + + std::cout << "Publishing Contact\nFirst:" << msg->first_name << + " Last:" << msg->last_name << std::endl; + + contact_publisher_->publish(msg); + }; + timer_ = this->create_wall_timer(1s, publish_msg); + } + + private: + rclcpp::Publisher::SharedPtr contact_publisher_; + rclcpp::timer::TimerBase::SharedPtr timer_; + }; + + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + + auto publisher_node = std::make_shared(); + + rclcpp::spin(publisher_node); + + return 0; + } + +The code explained +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c++ + + #include "rosidl_tutorials_msgs/msg/contact.hpp" + +Here we include the header of the message that we want to use. + +.. code-block:: c++ + + ContactPublisher() + : Node("address_book_publisher") + { + +Here we define a node + +.. code-block:: c++ + + auto publish_msg = [this]() -> void { + +A publish_msg function to send our message periodically + +.. code-block:: c++ + + auto msg = std::make_shared(); + + msg->first_name = "John"; + msg->last_name = "Doe"; + msg->age = 30; + msg->gender = msg->MALE; + msg->address = "unknown"; + +We create a Contact message and populate its fields. + +.. code-block:: c++ + + std::cout << "Publishing Contact\nFirst:" << msg->first_name << + " Last:" << msg->last_name << std::endl; + + contact_publisher_->publish(msg); + +Finally we publish it + +.. code-block:: c++ + + timer_ = this->create_wall_timer(1s, publish_msg); + +Create a 1second timer to call our ``publish_msg`` function every second + +Now let's build it! + +To use this message we need to declare a dependency on rosidl_tutorials_msgs in the ``package.xml``\ : + +.. code-block:: xml + + rosidl_tutorials_msgs + + rosidl_tutorials_msgs + +And also in the ``CMakeLists.txt``\ : + +.. code-block:: cmake + + find_package(rosidl_tutorials_msgs REQUIRED) + +And finally we must declare the message package as a target dependency for the executable. + +.. code-block:: cmake + + ament_target_dependencies(publish_contact + "rclcpp" + "rosidl_tutorials_msgs" + ) + +Using msg/srv from the same package +----------------------------------- + +While most of the time messages are declared in interface packages, it can be convenient to declare, create and use messages all in the one package. + +We will create a message in our rosidl_tutorials package. +Create a msg directory in the rosidl_tutorials package and AddressBook.msg inside that directory. +In that msg paste: + +.. code-block:: + + rosidl_tutorials_msgs/Contact[] address_book + +As you can see we define a message based on the Contact message we created earlier. + +To generate this message we need to declare a dependency on this package in the ``package.xml``\ : + +.. code-block:: xml + + rosidl_tutorials_msgs + + rosidl_tutorials_msgs + +And in the ``CMakeLists.txt``\ : + +.. code-block:: cmake + + find_package(rosidl_tutorials_msgs REQUIRED) + + set(msg_files + "msg/AddressBook.msg" + ) + + rosidl_generate_interfaces(${PROJECT_NAME} + ${msg_files} + DEPENDENCIES rosidl_tutorials_msgs + ) + +Now we can start writing code that uses this message. + +Open src/publish_address_book.cpp: + +.. code-block:: c++ + + #include + #include + + #include "rclcpp/rclcpp.hpp" + + #include "rosidl_tutorials/msg/address_book.hpp" + #include "rosidl_tutorials_msgs/msg/contact.hpp" + + using namespace std::chrono_literals; + + class AddressBookPublisher : public rclcpp::Node + { + public: + AddressBookPublisher() + : Node("address_book_publisher") + { + address_book_publisher_ = + this->create_publisher("address_book"); + + auto publish_msg = [this]() -> void { + auto msg = std::make_shared(); + { + rosidl_tutorials_msgs::msg::Contact contact; + contact.first_name = "John"; + contact.last_name = "Doe"; + contact.age = 30; + contact.gender = contact.MALE; + contact.address = "unknown"; + msg->address_book.push_back(contact); + } + { + rosidl_tutorials_msgs::msg::Contact contact; + contact.first_name = "Jane"; + contact.last_name = "Doe"; + contact.age = 20; + contact.gender = contact.FEMALE; + contact.address = "unknown"; + msg->address_book.push_back(contact); + } + + std::cout << "Publishing address book:" << std::endl; + for (auto contact : msg->address_book) { + std::cout << "First:" << contact.first_name << " Last:" << contact.last_name << + std::endl; + } + + address_book_publisher_->publish(msg); + }; + timer_ = this->create_wall_timer(1s, publish_msg); + } + + private: + rclcpp::Publisher::SharedPtr address_book_publisher_; + rclcpp::timer::TimerBase::SharedPtr timer_; + }; + + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + auto publisher_node = std::make_shared(); + + rclcpp::spin(publisher_node); + + return 0; + } + +The code explained +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c++ + + #include "rosidl_tutorials/msg/address_book.hpp" + +We include the header of our newly created AddressBook msg. + +.. code-block:: c++ + + #include "rosidl_tutorials_msgs/msg/contact.hpp" + +Here we include the header of the Contact msg in order to be able to add contacts to our address_book. + +.. code-block:: c++ + + using namespace std::chrono_literals; + + class AddressBookPublisher : public rclcpp::Node + { + public: + AddressBookPublisher() + : Node("address_book_publisher") + { + address_book_publisher_ = + this->create_publisher("address_book"); + +We create a node and an AddressBook publisher. + +.. code-block:: c++ + + auto publish_msg = [this]() -> void { + +We create a callback to publish the messages periodically + +.. code-block:: c++ + + auto msg = std::make_shared(); + +We create an AddressBook message instance that we will later publish. + +.. code-block:: c++ + + { + rosidl_tutorials_msgs::msg::Contact contact; + contact.first_name = "John"; + contact.last_name = "Doe"; + contact.age = 30; + contact.gender = contact.MALE; + contact.address = "unknown"; + msg->address_book.push_back(person); + } + { + rosidl_tutorials_msgs::msg::Contact person; + contact.first_name = "Jane"; + contact.last_name = "Doe"; + contact.age = 20; + contact.gender = contact.FEMALE; + contact.address = "unknown"; + msg->address_book.push_back(contact); + } + +We create and populate Contact messages and add them to our address_book message. + +.. code-block:: c++ + + std::cout << "Publishing address book:" << std::endl; + for (auto contact : msg->address_book) { + std::cout << "First:" << contact.first_name << " Last:" << contact.last_name << + std::endl; + } + + address_book_publisher_->publish(msg); + +Finally send the message periodically. + +.. code-block:: c++ + + timer_ = this->create_wall_timer(1s, publish_msg); + +Create a 1second timer to call our ``publish_msg`` function every second + +Now let's build it! +We need to create a new target for this node in the ``CMakeLists.txt``\ : + +.. code-block:: cmake + + add_executable(publish_address_book + src/publish_address_book.cpp + ) + + ament_target_dependencies(publish_address_book + "rclcpp" + ) + +In order to use the messages generated in the same package we need to use the following cmake code: + +.. code-block:: cmake + + get_default_rmw_implementation(rmw_implementation) + find_package("${rmw_implementation}" REQUIRED) + get_rmw_typesupport(typesupport_impls "${rmw_implementation}" LANGUAGE "cpp") + + foreach(typesupport_impl ${typesupport_impls}) + rosidl_target_interfaces(publish_address_book + ${PROJECT_NAME} ${typesupport_impl} + ) + endforeach() + +This finds the relevant generated C++ code from msg/srv and allows your target to link against them. + +You may have noticed that this step was not necessary when the interfaces being used were from a package that was built beforehand. +This CMake code is only required when you are trying to use interfaces in the same package as that in which they are built. diff --git a/Run-2-nodes-in-a-single-docker-container.md b/Run-2-nodes-in-a-single-docker-container.md deleted file mode 100644 index f19f406818a..00000000000 --- a/Run-2-nodes-in-a-single-docker-container.md +++ /dev/null @@ -1,27 +0,0 @@ -Pull the ROS2 docker image with tag "ardent-basic". - - docker pull osrf/ros2:ardent-basic - -Run the image in a container in interactive mode. - - $ docker run -it osrf/ros2:ardent-basic - root@:/# - -Your best friend is the `ros2` command line help now. - - root@:/# ros2 --help - -E.g. list all installed packages. - - root@:/# ros2 pkg list - (you will see a list of packages) - -E.g. list all executables: - - root@:/# ros2 pkg executables - (you will see a list of ) - -Run a minimal example of 2 C++ nodes (1 topic subscriber `listener`, 1 topic publisher `talker`) from the package `demo_nodes_cpp` in this container. - - ros2 run demo_nodes_cpp listener & - ros2 run demo_nodes_cpp talker \ No newline at end of file diff --git a/Run-2-nodes-in-a-single-docker-container.rst b/Run-2-nodes-in-a-single-docker-container.rst new file mode 100644 index 00000000000..6b28476910e --- /dev/null +++ b/Run-2-nodes-in-a-single-docker-container.rst @@ -0,0 +1,45 @@ + +Pull the ROS2 docker image with tag "ardent-basic". + +.. code-block:: + + docker pull osrf/ros2:ardent-basic + + +Run the image in a container in interactive mode. + +.. code-block:: + + $ docker run -it osrf/ros2:ardent-basic + root@:/# + + +Your best friend is the ``ros2`` command line help now. + +.. code-block:: + + root@:/# ros2 --help + + +E.g. list all installed packages. + +.. code-block:: + + root@:/# ros2 pkg list + (you will see a list of packages) + + +E.g. list all executables: + +.. code-block:: + + root@:/# ros2 pkg executables + (you will see a list of ) + + +Run a minimal example of 2 C++ nodes (1 topic subscriber ``listener``\ , 1 topic publisher ``talker``\ ) from the package ``demo_nodes_cpp`` in this container. + +.. code-block:: + + ros2 run demo_nodes_cpp listener & + ros2 run demo_nodes_cpp talker diff --git a/Set-up-a-new-Linux-CI-node.md b/Set-up-a-new-Linux-CI-node.md deleted file mode 100644 index a18f08613ba..00000000000 --- a/Set-up-a-new-Linux-CI-node.md +++ /dev/null @@ -1,69 +0,0 @@ -This page describes how to set up a linux machine for ROS2 CI jobs using AWS. - -# Creating an AWS instance -In short, use the company AWS account to launch an instance running based off the official Ubuntu 16.04 AMI. - -* **AMI:** Ubuntu 16.04 -* **Region:** N. California us-west-1a -* **Type:** c4.large -* **Storage:** EBS 1TB -* **Security Group:** `ROS 2 Jenkins Build Machines` -* **Key pair:** Create a new pair with a descriptive name like `ci_ros2_linux_4` - * Make sure to save it with the other credentials so others can access this machine - -Give the instance a descriptive name like `ROS2 CI (linux 4)`. -Record the ip address [here](https://docs.google.com/spreadsheets/d/1OSwqbE3qPF8v3HSMr8JOaJ6r4QOiQFk6pwgaudXVE-4/edit#gid=0) (private). - -# Setting up the machine -In short, make sure the jenkins master can ssh into the new node and run docker. - -1. Use the key pair to log into the new node - * `ssh -i ci_ros2_linux_4.pem ubuntu@IPADDRESS` -1. Run the following commands - - ``` - sudo apt update - sudo apt install -y git - sudo apt install -y openjdk-8-jre-headless - sudo bash -c 'echo "deb http://repositories.ros.org/ubuntu/testing/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' - sudo bash -c 'curl --silent http://repositories.ros.org/repos.key |sudo apt-key add -' - sudo apt update - sudo apt install -y python-vcstool - curl -fsSL https://get.docker.com/ | sh - sudo adduser --disabled-password jenkins - sudo usermod -aG docker jenkins - sudo service docker start - ``` -1. Make sure the jenkins user can run docker - - ``` - sudo su jenkins - docker run hello-world - ``` -1. As the jenkins user, add the master's public key to `authorized_keys` - 1. SSH into the jenkins master and get the contents of the public key (probably at /var/lib/jenkins/.ssh/id_rsa.pub, or wherever the home directory of the jenkins user is) - 2. SSH into the new slave and add that key to the authorized keylist - ``` - # on new slave - cd /home/jenkins/ - mkdir .ssh - chmod 700 .ssh - touch .ssh/authorized_keys - chmod 600 .ssh/authorized_keys - # Paste id_rsa.pub from the jenkins master into this file - vim .ssh/authorized_keys - ``` - -# Adding it to the master -1. Add a new agent to http://ci.ros2.org/computer/ - * **Number of executors:** 1 - * **Remote root directory:** /home/jenkins - * **Labels:** `linux` - * **Launch method:** Launch slave agents via ssh - * **Host:** Ip address of new node - * **Credentials:** `Jenkins` - * **Host Key Verification Strategy:** `Manually provided key verification strategy` - * **SSH Key** paste the contents of `/etc/ssh/ssh_host_rsa_key.pub` from the new node here. - * **Node Properties:** - * Check `Notify when Node online status changes` and set the email to the ros2 buildfarm google group. -2. Launch the agent on the new node \ No newline at end of file diff --git a/Set-up-a-new-Linux-CI-node.rst b/Set-up-a-new-Linux-CI-node.rst new file mode 100644 index 00000000000..4678759f727 --- /dev/null +++ b/Set-up-a-new-Linux-CI-node.rst @@ -0,0 +1,93 @@ + +This page describes how to set up a linux machine for ROS2 CI jobs using AWS. + +Creating an AWS instance +======================== + +In short, use the company AWS account to launch an instance running based off the official Ubuntu 16.04 AMI. + + +* **AMI:** Ubuntu 16.04 +* **Region:** N. California us-west-1a +* **Type:** c4.large +* **Storage:** EBS 1TB +* **Security Group:** ``ROS 2 Jenkins Build Machines`` +* **Key pair:** Create a new pair with a descriptive name like ``ci_ros2_linux_4`` + + * Make sure to save it with the other credentials so others can access this machine + +Give the instance a descriptive name like ``ROS2 CI (linux 4)``. +Record the ip address `here `__ (private). + +Setting up the machine +====================== + +In short, make sure the jenkins master can ssh into the new node and run docker. + + +#. Use the key pair to log into the new node + + * ``ssh -i ci_ros2_linux_4.pem ubuntu@IPADDRESS`` + +#. + Run the following commands + + .. code-block:: + + sudo apt update + sudo apt install -y git + sudo apt install -y openjdk-8-jre-headless + sudo bash -c 'echo "deb http://repositories.ros.org/ubuntu/testing/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' + sudo bash -c 'curl --silent http://repositories.ros.org/repos.key |sudo apt-key add -' + sudo apt update + sudo apt install -y python-vcstool + curl -fsSL https://get.docker.com/ | sh + sudo adduser --disabled-password jenkins + sudo usermod -aG docker jenkins + sudo service docker start + +#. + Make sure the jenkins user can run docker + + .. code-block:: + + sudo su jenkins + docker run hello-world + +#. As the jenkins user, add the master's public key to ``authorized_keys`` + + #. SSH into the jenkins master and get the contents of the public key (probably at /var/lib/jenkins/.ssh/id_rsa.pub, or wherever the home directory of the jenkins user is) + #. SSH into the new slave and add that key to the authorized keylist + .. code-block:: + + # on new slave + cd /home/jenkins/ + mkdir .ssh + chmod 700 .ssh + touch .ssh/authorized_keys + chmod 600 .ssh/authorized_keys + # Paste id_rsa.pub from the jenkins master into this file + vim .ssh/authorized_keys + +Adding it to the master +======================= + + +#. Add a new agent to http://ci.ros2.org/computer/ + + * **Number of executors:** 1 + * **Remote root directory:** /home/jenkins + * **Labels:** ``linux`` + * **Launch method:** Launch slave agents via ssh + + * **Host:** Ip address of new node + * **Credentials:** ``Jenkins`` + * **Host Key Verification Strategy:** ``Manually provided key verification strategy`` + + * **SSH Key** paste the contents of ``/etc/ssh/ssh_host_rsa_key.pub`` from the new node here. + + * **Node Properties:** + + * Check ``Notify when Node online status changes`` and set the email to the ros2 buildfarm google group. + +#. Launch the agent on the new node diff --git a/Set-up-a-new-Windows-CI-node.md b/Set-up-a-new-Windows-CI-node.rst similarity index 65% rename from Set-up-a-new-Windows-CI-node.md rename to Set-up-a-new-Windows-CI-node.rst index cac1c63fc3b..4274c8c8a57 100644 --- a/Set-up-a-new-Windows-CI-node.md +++ b/Set-up-a-new-Windows-CI-node.rst @@ -1,44 +1,52 @@ + Note: See this older (private) document for previous instructions: https://docs.google.com/document/d/1SmmWa7MVnwjmMw9XJF33-fsa0dtkYj2AeEXBa8BCsYs/edit -### Install and Update Windows 10 +Install and Update Windows 10 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We use the normal Windows 10 version, not the enterprise, but other than that we just do system updates and use default settings otherwise. -### Install Dependencies for ROS 2 +Install Dependencies for ROS 2 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Follow our Windows "from source" [installation instructions](Windows-Development-Setup.md). +Follow our Windows "from source" `installation instructions `. -### Setup git +Setup git +^^^^^^^^^ Ensure that the git installation has a (garbage) email and name, otherwise it will fail if it ever needs to make merge commits when merging branches with "master". Note that this must be done in the context of the "System" user, which is what the Jenkins service will run as. -- Become the system user by using `psexec`: - - Download it from: https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx - - Then extract the zip, open a command-prompt as administrator, and run: `psexec -i -s cmd.exe` + +* Become the system user by using ``psexec``\ : + + * Download it from: https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx + * Then extract the zip, open a command-prompt as administrator, and run: ``psexec -i -s cmd.exe`` This is all pieced together from a couple of pages here: -- http://blog.thomasvandoren.com/jenkins-windows-slave-with-git.html -- https://answers.atlassian.com/questions/128324/where-is-the-home-directory-for-the-system-user + +* http://blog.thomasvandoren.com/jenkins-windows-slave-with-git.html +* https://answers.atlassian.com/questions/128324/where-is-the-home-directory-for-the-system-user Once you are the system user, set the git config: -``` -> git config --global user.email "noreply@osrfoundation.org" -> git config --global user.name "nobody" -``` +.. code-block:: + + > git config --global user.email "noreply@osrfoundation.org" + > git config --global user.name "nobody" -### Setup Jenkins Agent +Setup Jenkins Agent +^^^^^^^^^^^^^^^^^^^ Download and install Java from Oracle: https://java.com/en/download/ -Create the `C:\J` folder. +Create the ``C:\J`` folder. Go to http://ci.ros2.org and select: Manage Jenkins -> Manage Nodes -> New node @@ -46,17 +54,18 @@ Copy an existing node and choose a working windows node (at the time of the writ Hit the "launch" button to download the "Java Web Start App" and save it on the desktop. -Open an Administrator `cmd.exe` and then: +Open an Administrator ``cmd.exe`` and then: + +.. code-block:: -``` -> cd \path\to\downloaded\file -> .\slave-agent.jnlp -``` + > cd \path\to\downloaded\file + > .\slave-agent.jnlp Once open, go to File->"Install as a Service". Then you can close the slave agent as it will start on boot. -### Install RTI Connext +Install RTI Connext +^^^^^^^^^^^^^^^^^^^ Download and install Connext binary: diff --git a/Set-up-a-new-macOS-CI-node.md b/Set-up-a-new-macOS-CI-node.md deleted file mode 100644 index 67dad97832f..00000000000 --- a/Set-up-a-new-macOS-CI-node.md +++ /dev/null @@ -1,115 +0,0 @@ -Note: Last installed/updated on 2017-11-20 (Mac OS 10.13.1 High Sierra) and see this older (private) document for previous instructions: - -https://docs.google.com/document/d/1J_8O7Q7eiixC-axyjP_bVpZSALyhn67Y1K_-SAw5eh0/edit - ----- - -### Install macOS High Sierra - -Install: APFS case-sensitive -Post-install: No Siri, no location services, no cloud anything, no analytics, no filevault disk encryption. - -### Setup SSH/VNC for Remote Access - -Make sure you don't use too long of a password. -That makes VNC auth fail in bizarre ways. -In particular, VNC auth limits you to 8 characters. - -- Go to: Apple->System Preferences->Sharing - - set hostname to something reasonable - - check "Remote Login" - - check "Screen Sharing" -- add Terminal to the dock -- Go to: Apple->System Preferences->Energy Saver - - set sleep to never - - uncheck everything -- Go to: Apple->Security - - click lock to unlock it - - "Allow Apps from app store and verified developers" - - uncheck "Require password after 5 minutes" box - - uncheck "Disable automatic login" - -### ROS 2 CI Host Setup - -Install XCode tools: - -``` -$ xcode select --install -``` - -Install JDK for Jenkins. -Easiest way is to type `java` at the terminal and let Apple link you to Oracle’s JDK download. -I installed the latest JDK 8 (withholding Java 9 for now). - -Install Homebrew following instructions at https://brew.sh - -Install `ssh-askpass` via homebrew - -``` -$ brew tap theseal/ssh-askpass -$ brew install ssh-askpass -``` - -create `~/.bash_profile` with this one line: - -```bash -. ~/.bashrc -``` - -create `~/.bashrc` with one line: - -```bash -export ROS_DOMAIN_ID=XXX # where XXX is chosen from this document -``` - -set up dummy git names: - -``` -$ git config --global user.email "nobody@osrfoundation.org" -$ git config --global user.name "HOSTNAME" -``` - -### Install ROS 2 Dependencies - -Install them according to [our install instructions](OSX-Development-Setup.md). - -Including: - -- brew packages -- pip packages -- the optional RTI Connext and OpenSplice packages -- everything but downloading the source and building ROS 2 (unless you want to do so for testing the setup) - -#### RTI Connext Specific Instructions - -- The Open Robotics license is here (private repo): https://github.com/osrf/rticonnextdds-src/blob/license/rti_license.dat -- Open the RTI launcher application - - In the RTI launcher, open the file dialog to choose the license file. - - Install it for all users. - - Click the Installation tab - - Click RTI Package installer -- Navigate to the connext extracted directory (usually something like `/Applications/rti_...` - - Select the `rti_security rtipkg` (don’t bother with the openssl ones, we use system openssl) -- Set the shared memory parameters from https://community.rti.com/kb/osx510 - - Do not bother to reboot yet. - -### Setting up the Jenkins Workspace and Agent - -``` -$ mkdir jenkins jenkins-agent -$ cd jenkins-agent -$ wget http://ci.ros2.org/jnlpJars/slave.jar -``` - -Copy the jenkins agent plist from https://gist.github.com/nuclearsandwich/c9546e76ba63767bc1025c393e85235b - -Edit the file to match the jnlp url and secret of the host you’re setting up. -You may need to create a new agent if you’re not re-imaging an existing one. - -``` -$ mkdir ~/Library/LaunchAgents -$ cp ~/jenkins-agent/org.ros2.ci.jenkins-agent.plist ~/Library/LaunchAgents -$ launchctl load -w ~/Library/LaunchAgents/org.ros2.ci.jenkins-agent.plist -``` - -Reboot! You should be good to go, run some test CI jobs. \ No newline at end of file diff --git a/Set-up-a-new-macOS-CI-node.rst b/Set-up-a-new-macOS-CI-node.rst new file mode 100644 index 00000000000..a7139df3542 --- /dev/null +++ b/Set-up-a-new-macOS-CI-node.rst @@ -0,0 +1,135 @@ + +Note: Last installed/updated on 2017-11-20 (Mac OS 10.13.1 High Sierra) and see this older (private) document for previous instructions: + +https://docs.google.com/document/d/1J_8O7Q7eiixC-axyjP_bVpZSALyhn67Y1K_-SAw5eh0/edit + +---- + +Install macOS High Sierra +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Install: APFS case-sensitive +Post-install: No Siri, no location services, no cloud anything, no analytics, no filevault disk encryption. + +Setup SSH/VNC for Remote Access +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Make sure you don't use too long of a password. +That makes VNC auth fail in bizarre ways. +In particular, VNC auth limits you to 8 characters. + + +* Go to: Apple->System Preferences->Sharing + + * set hostname to something reasonable + * check "Remote Login" + * check "Screen Sharing" + +* add Terminal to the dock +* Go to: Apple->System Preferences->Energy Saver + + * set sleep to never + * uncheck everything + +* Go to: Apple->Security + + * click lock to unlock it + * "Allow Apps from app store and verified developers" + * uncheck "Require password after 5 minutes" box + * uncheck "Disable automatic login" + +ROS 2 CI Host Setup +^^^^^^^^^^^^^^^^^^^ + +Install XCode tools: + +.. code-block:: + + $ xcode select --install + +Install JDK for Jenkins. +Easiest way is to type ``java`` at the terminal and let Apple link you to Oracle’s JDK download. +I installed the latest JDK 8 (withholding Java 9 for now). + +Install Homebrew following instructions at https://brew.sh + +Install ``ssh-askpass`` via homebrew + +.. code-block:: + + $ brew tap theseal/ssh-askpass + $ brew install ssh-askpass + +create ``~/.bash_profile`` with this one line: + +.. code-block:: bash + + . ~/.bashrc + +create ``~/.bashrc`` with one line: + +.. code-block:: bash + + export ROS_DOMAIN_ID=XXX # where XXX is chosen from this document + +set up dummy git names: + +.. code-block:: + + $ git config --global user.email "nobody@osrfoundation.org" + $ git config --global user.name "HOSTNAME" + +Install ROS 2 Dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Install them according to `our install instructions `. + +Including: + + +* brew packages +* pip packages +* the optional RTI Connext and OpenSplice packages +* everything but downloading the source and building ROS 2 (unless you want to do so for testing the setup) + +RTI Connext Specific Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +* The Open Robotics license is here (private repo): https://github.com/osrf/rticonnextdds-src/blob/license/rti_license.dat +* Open the RTI launcher application + + * In the RTI launcher, open the file dialog to choose the license file. + * Install it for all users. + * Click the Installation tab + * Click RTI Package installer + +* Navigate to the connext extracted directory (usually something like ``/Applications/rti_...`` + + * Select the ``rti_security rtipkg`` (don’t bother with the openssl ones, we use system openssl) + +* Set the shared memory parameters from https://community.rti.com/kb/osx510 + + * Do not bother to reboot yet. + +Setting up the Jenkins Workspace and Agent +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: + + $ mkdir jenkins jenkins-agent + $ cd jenkins-agent + $ wget http://ci.ros2.org/jnlpJars/slave.jar + +Copy the jenkins agent plist from https://gist.github.com/nuclearsandwich/c9546e76ba63767bc1025c393e85235b + +Edit the file to match the jnlp url and secret of the host you’re setting up. +You may need to create a new agent if you’re not re-imaging an existing one. + +.. code-block:: + + $ mkdir ~/Library/LaunchAgents + $ cp ~/jenkins-agent/org.ros2.ci.jenkins-agent.plist ~/Library/LaunchAgents + $ launchctl load -w ~/Library/LaunchAgents/org.ros2.ci.jenkins-agent.plist + +Reboot! You should be good to go, run some test CI jobs. diff --git a/Tutorials.md b/Tutorials.md deleted file mode 100644 index 8272395b447..00000000000 --- a/Tutorials.md +++ /dev/null @@ -1,66 +0,0 @@ -## About ROS 2 -* [Overview of ROS 2 concepts](Overview-of-ROS-2-concepts.md) -* [DDS and ROS middleware implementations](DDS-and-ROS-middleware-implementations.md) -* [ROS 2 Client Libraries](ROS-2-Client-Libraries.md) -* [About ROS interfaces](About-ROS-interfaces.md) -* [About Quality of Service Settings](About-Quality-of-Service-Settings.md) - - -## ROS 2 Tutorials -* [Installation from binary and source, all platforms](Installation.md) -* [Using colcon to build a custom package](Colcon-Tutorial.md) -* [Introspection with command-line tools](Introspection-with-command-line-tools.md) -* [Passing ROS arguments to nodes via the command-line](Node-arguments.md) -* [Launching/monitoring multiple nodes with Launch](Launch-system.md) -* [Working with multiple RMW implementations](Working-with-multiple-RMW-implementations.md) -* [Composing multiple nodes in a single process](Composition.md) -* [Defining custom interfaces (msg/srv)](Defining-custom-interfaces-(msg/srv).md) -* [New features in ROS 2 interfaces (msg srv)](New-features-in-ROS-2-interfaces-(msg-srv).md) -* [Eclipse Oxygen with ROS 2 and rviz2](Eclipse-Oxygen-with-ROS-2-and-rviz2.md) [community-contributed] -* [Building ROS 2 on Linux with Eclipse Oxygen](Building-ROS-2-on-Linux-with-Eclipse-Oxygen.md) [community-contributed] -* [Building Realtime rt_preempt kernel for ROS 2](Building-Realtime-rt_preempt-kernel-for-ROS-2.md) [community-contributed] - -### Advanced -* [Implement a custom memory allocator](Allocator-Template-Tutorial.md) - -### Docker - -* [Run 2 nodes in a single docker container](Run-2-nodes-in-a-single-docker-container.md) [community-contributed] -* [Run 2 nodes in two separate docker containers](Run-2-nodes-in-two-separate-docker-containers.asciidoc) [community-contributed] - -## ROS 2 Demos -* [Use quality-of-service settings to handle lossy networks](Quality-of-Service.md) -* [Management of nodes with managed lifecycles](Managed-Nodes.md) -* [Efficient intra-process communication](Intra-Process-Communication.md) -* [Bridge communication between ROS 1 and ROS 2](https://github.com/ros2/ros1_bridge/blob/master/README.md) -* [Recording and playback of topic data with rosbag using the ROS 1 bridge](Rosbag-with-ROS1-Bridge.md) -* [Turtlebot 2 demo using ROS 2](https://github.com/ros2/turtlebot2_demo) -* [TurtleBot 3 demo using ROS 2](http://emanual.robotis.com/docs/en/platform/turtlebot3/applications/#ros2) [community-contributed] -* [Using tf2 with ROS 2](tf2.md) -* [Write real-time safe code that uses the ROS 2 APIs](Real-Time-Programming.md) -* [Use the rclpy API to write ROS 2 programs in Python](Python-Programming.md) -* [Use the robot state publisher to publish joint states and TF](dummy-robot-demo.md) -* [Use DDS-Security](https://github.com/ros2/sros2/blob/master/README.md) -* [Logging and logger configuration](Logging-and-logger-configuration.md) - - -## ROS 2 Examples -* [Python and C++ minimal examples](https://github.com/ros2/examples) - - -## Troubleshooting - -### Enable Multicast -In order to communicate successfully via DDS, the used network interface has to be multicast enabled. -We've seen in past experiences that this might not necessarily be enabled by default (on Ubuntu or OSX) when using the loopback adapter. -See the [original issue](https://github.com/ros2/ros2/issues/552) or a [conversation on ros-answers](https://answers.ros.org/question/300370/ros2-talker-cannot-communicate-with-listener/). -You can verify that your current setup allows multicast with the ROS 2 tool: - -In Terminal 1: -``` -ros2 multicast receive -``` -In Terminal 2: -``` -ros2 multicast send -``` diff --git a/Tutorials.rst b/Tutorials.rst new file mode 100644 index 00000000000..1c902ef878b --- /dev/null +++ b/Tutorials.rst @@ -0,0 +1,87 @@ + +About ROS 2 +----------- + + +* `Overview of ROS 2 concepts ` +* `DDS and ROS middleware implementations ` +* `ROS 2 Client Libraries ` +* `About ROS interfaces ` +* `About Quality of Service Settings ` + +ROS 2 Tutorials +--------------- + + +* `Installation from binary and source, all platforms ` +* `Using colcon to build a custom package ` +* `Introspection with command-line tools ` +* `Passing ROS arguments to nodes via the command-line ` +* `Launching/monitoring multiple nodes with Launch ` +* `Working with multiple RMW implementations ` +* `Composing multiple nodes in a single process ` +* `Defining custom interfaces (msg/srv) `) +* `New features in ROS 2 interfaces (msg srv) `) +* `Eclipse Oxygen with ROS 2 and rviz2 ` [community-contributed] +* `Building ROS 2 on Linux with Eclipse Oxygen ` [community-contributed] +* `Building Realtime rt_preempt kernel for ROS 2 ` [community-contributed] + +Advanced +^^^^^^^^ + + +* `Implement a custom memory allocator ` + +Docker +^^^^^^ + + +* `Run 2 nodes in a single docker container ` [community-contributed] +* `Run 2 nodes in two separate docker containers ` [community-contributed] + +ROS 2 Demos +----------- + + +* `Use quality-of-service settings to handle lossy networks ` +* `Management of nodes with managed lifecycles ` +* `Efficient intra-process communication ` +* `Bridge communication between ROS 1 and ROS 2 `__ +* `Recording and playback of topic data with rosbag using the ROS 1 bridge ` +* `Turtlebot 2 demo using ROS 2 `__ +* `TurtleBot 3 demo using ROS 2 `__ [community-contributed] +* `Using tf2 with ROS 2 ` +* `Write real-time safe code that uses the ROS 2 APIs ` +* `Use the rclpy API to write ROS 2 programs in Python ` +* `Use the robot state publisher to publish joint states and TF ` +* `Use DDS-Security `__ +* `Logging and logger configuration ` + +ROS 2 Examples +-------------- + + +* `Python and C++ minimal examples `__ + +Troubleshooting +--------------- + +Enable Multicast +^^^^^^^^^^^^^^^^ + +In order to communicate successfully via DDS, the used network interface has to be multicast enabled. +We've seen in past experiences that this might not necessarily be enabled by default (on Ubuntu or OSX) when using the loopback adapter. +See the `original issue `__ or a `conversation on ros-answers `__. +You can verify that your current setup allows multicast with the ROS 2 tool: + +In Terminal 1: + +.. code-block:: + + ros2 multicast receive + +In Terminal 2: + +.. code-block:: + + ros2 multicast send diff --git a/Windows-Development-Setup.md b/Windows-Development-Setup.md deleted file mode 100644 index f14633dfd26..00000000000 --- a/Windows-Development-Setup.md +++ /dev/null @@ -1,334 +0,0 @@ -# Building ROS 2 on Windows - -This guide is about how to setup a development environment for ROS2 on Windows. - -## Prerequisites - -First follow the steps for [Installing Prerequisites](Windows-Install-Binary.md#installing-prerequisites) on the Binary Installation page. - -Stop and return here when you reach the "Downloading ROS 2" section. - -### Additional Prerequisites - -When building from source you'll need a few additional prerequisites installed. - -#### Install Additional Prerequisites from Chocolatey - -First install git: - -``` -> choco install -y git -``` - -You will need to append the Git cmd folder `C:\Program Files\Git\cmd` to the PATH (you can do this by clicking the Windows icon, typing "Environment Variables", then clicking on "Edit the system environment variables". -In the resulting dialog, click "Environment Variables", the click "Path" on the bottom pane, then click "Edit" and add the path). - -Then install `patch`: - -``` -> choco install -y patch -``` - -You may need to close the cmd prompt and open a new one, but at this point you should be able to run `git`, `python`, `cmake`, and `patch.exe --version`. - -#### Installing Developer Tools - -Now we are ready to install some our tools that we use to help in developing ROS 2. - -Let's start with `vcstool`: - -``` -> pip install -U vcstool -``` - -You can test it out by just running `vcs` (you should be able to do this in the same cmd prompt). - -Next, install `colcon`: - -``` -> pip install -U colcon-common-extensions -``` - -You can test it out by just running `colcon` (you should be able to do this in the same cmd prompt). - -Also, you should install `curl`: - -``` -> choco install -y curl -``` - -### Install dependencies - -Next install the latest version of `setuptools` and `pip`: - -``` -> -m pip install -U setuptools pip -``` -Where `PATH_TO_PYTHON_EXECUTABLE` looks like: `c:\python37\python.exe` - -Then you can continue installing other Python dependencies: - -``` -> pip install -U catkin_pkg EmPy pyparsing pyyaml -``` - -Next install testing tools like `pytest` and others: - -``` -> pip install -U pytest coverage mock -``` - -Next install linters and checkers like `flake8` and others: - -``` -> pip install -U flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes pep8 pydocstyle -``` - -Next install cppcheck: - -``` -> choco install -y cppcheck -``` - -You will need to add `C:\Program Files\Cppcheck` to the `PATH`. - -### Install Qt5 - -This section is only required if you are building rviz, but it comes with our default set of sources, so if you don't know, then assume you are building it. - -First get the installer from Qt's website: - -https://www.qt.io/download - -Select the Open Source version and then the `Qt Online Installer for Windows`. - -Run the installer and install Qt5. -We recommend you install it to the default location of `C:\Qt`, but if you choose somewhere else, make sure to update the paths below accordingly. -When selecting components to install, the only thing you absolutely need for bouncy and later is the appropriate MSVC 64-bit component under the `Qt` -> `Qt 5.10.0` tree. -We're using `5.10.0` as of the writing of this document and that's what we recommend since that's all we test on Windows, but later version will probably work too. -For bouncy and later, be sure to select `MSVC 2017 64-bit`. For ardent use `MSVC 2015 64-bit`. -After that, the default settings are fine. - -Finally, set the `Qt5_DIR` environment variable in the `cmd.exe` where you intend to build so that CMake can find it: - -``` -> set Qt5_DIR=C:\Qt\5.10.0\msvc2017_64 -: You could set it permanently with `setx -m Qt5_DIR C:\Qt\5.10.0\msvc2017_64` instead, but that requires Administrator. -``` - -Note, this path might change based on which MSVC version you're using or if you installed it to a different directory. - -### Getting the Source Code - -Now that we have the development tools we can get the ROS 2 source code. - -First setup a development folder, I use `C:\dev\ros2`: - -``` -> md \dev\ros2\src -> cd \dev\ros2 -``` - -Get the `ros2.repos` file which defines the repositories to clone from: - -``` -# CMD -> curl -sk https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos - -# PowerShell -> curl https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos -``` - -> Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing `release-latest` in the URL above with `master`. The `release-latest` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also [Maintaining a Source Checkout](Maintaining-a-Source-Checkout.md). - -Next you can use `vcs` to import the repositories listed in the `ros2.repos` file: - -``` -# CMD -> vcs import src < ros2.repos - -# PowerShell -> vcs import --input ros2.repos src -``` - -### Getting a DDS Vendor - -You'll also need a DDS Vendor available for ROS to build against. -There is currently support for eProsima FastRTPS, Adlink's OpenSplice, and RTI's Connext DDS. -The source distribution of ROS 2 includes FastRTPS, so it will always build unless explicitly ignored. - -#### Adlink OpenSplice - -If you would like to also build against OpenSplice, you will need to first download the latest version of [OpenSplice 6.7.180404](https://github.com/ADLINK-IST/opensplice/releases/tag/OSPL_V6_7_180404OSS_RELEASE%2BVS2017%2Bubuntu1804). -Then run something like the following command before building ROS 2, to set up the OpenSplice environment: - -``` -call "C:\opensplice67\HDE\x86_64.win64\release.bat" -``` - -where the exact paths may need to be slightly altered depending on where you selected to install OpenSplice. - -#### RTI Connext 5.3 - -If you would like to also build against RTI Connext, you will need to first visit the RTI website and obtain a license (evaluation or purchased) for RTI Connext DDS as well as the installer via their [downloads page](https://www.rti.com/downloads). -After installing, use the RTI Launcher to load your license file. -Then before building ROS 2, set up the Connext environment: - -``` -call "C:\Program Files\rti_connext_dds-5.3.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" -``` - -Note that this path might need to be slightly altered depending on where you selected to install RTI Connext DDS. -The path above is the current default path as of version 5.3.1, but will change as the version numbers increment in the future. - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -If you don't install any additional DDS vendors, ROS 2 will default to using eProsima's Fast-RTPS as the middleware. - -### Building the ROS 2 Code - -To build ROS 2 you will need a Visual Studio Command Prompt (usually titled "x64 Native Tools Command Prompt for VS 2017" for bouncy and later or "x64 Native Tools Command Prompt for VS 2015" for ardent and earlier) running as Administrator. - -FastRTPS is bundled with the ROS 2 source and will always be built unless you put an `AMENT_IGNORE` file in the `src\eProsima` folder. - -To build the `\dev\ros2` folder tree: - -``` -> colcon build --merge-install -``` - -Note, we're using `--merge-install` here to avoid a `PATH` variable that is too long at the end of the build. If you're adapting these instructions to build a smaller workspace then you might be able to use the default behavior which is isolated install, i.e. where each package is installed to a different folder. - -Note, if you are doing a debug build use `python_d path\to\colcon_executable` `colcon`. -See [this page](Windows-Development-Setup.md#extra-stuff-for-debug-mode) for more info on running Python code in debug builds on Windows. - -### Testing and Running - -Note that the first time you run any executable you will have to allow access to the network through a Windows Firewall popup. - -You can run the tests using this command: - -``` -> colcon test -``` - -Afterwards you can get a summary of the tests using this command: - -``` -> colcon test-result -``` - -To run the examples, first open a clean new `cmd.exe` and set up the workspace. -This is done by sourcing the `local_setup.bat` file, which will automatically set up the environment for any DDS vendors that support was built for. -Then execute the examples, e.g.: - -``` -> call install\local_setup.bat -> ros2 run demo_nodes_py talker -``` - -In a separate shell you can do the same, but instead run the `listener`: - -``` -> call install\local_setup.bat -> ros2 run demo_nodes_py listener -``` - -For more explanations see the [Python Programming](Python-Programming.md) demo or [other tutorials](Tutorials.md). - -Note: it is not recommended to build in the same cmd prompt that you've sourced the `local_setup.bat`. - -### Alternative DDS Sources - -The demos will attempt to build against any detected DDS vendor. -The only bundled vendor is eProsima's Fast RTPS, which is included in the default set of sources for ROS 2.0. -To build for other vendors, make sure that your chosen DDS vendor(s) are exposed in your environment when you run the build. -If you would like to change which vendor is being used see: [Working with Multiple RMW Implementations](Working-with-multiple-RMW-implementations.md) - -## Troubleshooting - -### CMake error setting modification time - -If you run into the CMake error `file INSTALL cannot set modification time on ...` when installing files it is likely that an anti virus software or Windows Defender are interfering with the build. E.g. for Windows Defender you can list the workspace location to be excluded to prevent it from scanning those files. - -### 260 Character Path Limit - -``` -The input line is too long. -The syntax of the command is incorrect. -``` - -You may see path length limit errors when building your own libraries, or maybe even in this guide as ROS2 matures. - -Run `regedit.exe`, navigate to `Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`, and set `LongPathsEnabled` to 0x00000001 (1). - -Hit the windows key and type `Edit Group Policy`. Navigate to Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem. Right click `Enable Win32 long paths`, click Edit. In the dialog, select Enabled and click OK. - -Close and open your terminal to reset the environment and try building again. - -### CMake Packages Unable to Find asio, tinyxml2, tinyxml, or eigen - -We've seen, but been unable to identify the root cause, that sometimes the chocolatey packages for `asio`, `tinyxml2`, etc. do not add important registry entries and that will cause CMake to be unable to find them when building ROS 2. - -It seems that uninstalling the chocolatey packages (with `-n` if the uninstall fails the first time) and then reinstalling them will fix the issue. - -### patch.exe Opens a New Command Window and Asks for Administrator - -This will also cause the build of packages which need to use patch to fail, even you allow it to use administrator rights. - -The solution, for now, is to make sure you're building in a Visual Studio command prompt which has been run as administrator. On some machines canceling the prompt without selecting "Yes" will also work. - -## Extra stuff for Debug mode - -If you want to be able to run all the tests in Debug mode, you'll need to install a few more things: - -* To be able to extract the Python source tarball, you can use PeaZip: - -``` -> choco install -y peazip -``` - -* You'll also need SVN, since some of the Python source-build dependencies are checked out via SVN: - -``` -> choco install -y svn hg -``` - -* You'll need to quit and restart the command prompt after installing the above. -* Get and extract the Python 3.7.0 source from the `tgz`: - * https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz - * To keep these instructions concise, please extract it to `C:\dev\Python-3.7.0` -* Now, build the Python source in debug mode from a Visual Studio command prompt: - -``` -> cd C:\dev\Python-3.7.0\PCbuild -> get_externals.bat -> build.bat -p x64 -d -``` - -* Finally, copy the build products into the Python37 installation directories, next to the Release-mode Python executable and DLL's: - -``` -> cd C:\dev\Python-3.7.0\PCbuild\amd64 -> copy python_d.exe C:\Python37 /Y -> copy python37_d.dll C:\Python37 /Y -> copy python3_d.dll C:\Python37 /Y -> copy python37_d.lib C:\Python37\libs /Y -> copy python3_d.lib C:\Python37\libs /Y -> for %I in (*_d.pyd) do copy %I C:\Python37\DLLs /Y -``` - -* Now, from a fresh command prompt, make sure that `python_d` works: - -``` -> python_d -> import _ctypes -``` - -* To create executables python scripts(.exe), python_d should be used to invoke colcon - -``` -> python_d path\to\colcon_executable build -``` - -* Hooray, you're done! diff --git a/Windows-Development-Setup.rst b/Windows-Development-Setup.rst new file mode 100644 index 00000000000..eea5bc17a6e --- /dev/null +++ b/Windows-Development-Setup.rst @@ -0,0 +1,368 @@ + +Building ROS 2 on Windows +========================= + +This guide is about how to setup a development environment for ROS2 on Windows. + +Prerequisites +------------- + +First follow the steps for `Installing Prerequisites ` on the Binary Installation page. + +Stop and return here when you reach the "Downloading ROS 2" section. + +Additional Prerequisites +^^^^^^^^^^^^^^^^^^^^^^^^ + +When building from source you'll need a few additional prerequisites installed. + +Install Additional Prerequisites from Chocolatey +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First install git: + +.. code-block:: + + > choco install -y git + +You will need to append the Git cmd folder ``C:\Program Files\Git\cmd`` to the PATH (you can do this by clicking the Windows icon, typing "Environment Variables", then clicking on "Edit the system environment variables". +In the resulting dialog, click "Environment Variables", the click "Path" on the bottom pane, then click "Edit" and add the path). + +Then install ``patch``\ : + +.. code-block:: + + > choco install -y patch + +You may need to close the cmd prompt and open a new one, but at this point you should be able to run ``git``\ , ``python``\ , ``cmake``\ , and ``patch.exe --version``. + +Installing Developer Tools +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now we are ready to install some our tools that we use to help in developing ROS 2. + +Let's start with ``vcstool``\ : + +.. code-block:: + + > pip install -U vcstool + +You can test it out by just running ``vcs`` (you should be able to do this in the same cmd prompt). + +Next, install ``colcon``\ : + +.. code-block:: + + > pip install -U colcon-common-extensions + +You can test it out by just running ``colcon`` (you should be able to do this in the same cmd prompt). + +Also, you should install ``curl``\ : + +.. code-block:: + + > choco install -y curl + +Install dependencies +^^^^^^^^^^^^^^^^^^^^ + +Next install the latest version of ``setuptools`` and ``pip``\ : + +.. code-block:: + + > -m pip install -U setuptools pip + +Where ``PATH_TO_PYTHON_EXECUTABLE`` looks like: ``c:\python37\python.exe`` + +Then you can continue installing other Python dependencies: + +.. code-block:: + + > pip install -U catkin_pkg EmPy pyparsing pyyaml + +Next install testing tools like ``pytest`` and others: + +.. code-block:: + + > pip install -U pytest coverage mock + +Next install linters and checkers like ``flake8`` and others: + +.. code-block:: + + > pip install -U flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes pep8 pydocstyle + +Next install cppcheck: + +.. code-block:: + + > choco install -y cppcheck + +You will need to add ``C:\Program Files\Cppcheck`` to the ``PATH``. + +Install Qt5 +^^^^^^^^^^^ + +This section is only required if you are building rviz, but it comes with our default set of sources, so if you don't know, then assume you are building it. + +First get the installer from Qt's website: + +https://www.qt.io/download + +Select the Open Source version and then the ``Qt Online Installer for Windows``. + +Run the installer and install Qt5. +We recommend you install it to the default location of ``C:\Qt``\ , but if you choose somewhere else, make sure to update the paths below accordingly. +When selecting components to install, the only thing you absolutely need for bouncy and later is the appropriate MSVC 64-bit component under the ``Qt`` -> ``Qt 5.10.0`` tree. +We're using ``5.10.0`` as of the writing of this document and that's what we recommend since that's all we test on Windows, but later version will probably work too. +For bouncy and later, be sure to select ``MSVC 2017 64-bit``. For ardent use ``MSVC 2015 64-bit``. +After that, the default settings are fine. + +Finally, set the ``Qt5_DIR`` environment variable in the ``cmd.exe`` where you intend to build so that CMake can find it: + +.. code-block:: + + > set Qt5_DIR=C:\Qt\5.10.0\msvc2017_64 + : You could set it permanently with `setx -m Qt5_DIR C:\Qt\5.10.0\msvc2017_64` instead, but that requires Administrator. + +Note, this path might change based on which MSVC version you're using or if you installed it to a different directory. + +Getting the Source Code +^^^^^^^^^^^^^^^^^^^^^^^ + +Now that we have the development tools we can get the ROS 2 source code. + +First setup a development folder, I use ``C:\dev\ros2``\ : + +.. code-block:: + + > md \dev\ros2\src + > cd \dev\ros2 + +Get the ``ros2.repos`` file which defines the repositories to clone from: + +.. code-block:: + + # CMD + > curl -sk https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos + + # PowerShell + > curl https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos -o ros2.repos + +.. + + Note: if you want to get all of the latest bug fixes then you can try the "tip" of development by replacing ``release-latest`` in the URL above with ``master``. The ``release-latest`` is preferred by default because it goes through more rigorous testing on release than changes to master do. See also `Maintaining a Source Checkout `. + + +Next you can use ``vcs`` to import the repositories listed in the ``ros2.repos`` file: + +.. code-block:: + + # CMD + > vcs import src < ros2.repos + + # PowerShell + > vcs import --input ros2.repos src + +Getting a DDS Vendor +^^^^^^^^^^^^^^^^^^^^ + +You'll also need a DDS Vendor available for ROS to build against. +There is currently support for eProsima FastRTPS, Adlink's OpenSplice, and RTI's Connext DDS. +The source distribution of ROS 2 includes FastRTPS, so it will always build unless explicitly ignored. + +Adlink OpenSplice +~~~~~~~~~~~~~~~~~ + +If you would like to also build against OpenSplice, you will need to first download the latest version of `OpenSplice 6.7.180404 `__. +Then run something like the following command before building ROS 2, to set up the OpenSplice environment: + +.. code-block:: + + call "C:\opensplice67\HDE\x86_64.win64\release.bat" + +where the exact paths may need to be slightly altered depending on where you selected to install OpenSplice. + +RTI Connext 5.3 +~~~~~~~~~~~~~~~ + +If you would like to also build against RTI Connext, you will need to first visit the RTI website and obtain a license (evaluation or purchased) for RTI Connext DDS as well as the installer via their `downloads page `__. +After installing, use the RTI Launcher to load your license file. +Then before building ROS 2, set up the Connext environment: + +.. code-block:: + + call "C:\Program Files\rti_connext_dds-5.3.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" + +Note that this path might need to be slightly altered depending on where you selected to install RTI Connext DDS. +The path above is the current default path as of version 5.3.1, but will change as the version numbers increment in the future. + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +If you don't install any additional DDS vendors, ROS 2 will default to using eProsima's Fast-RTPS as the middleware. + +Building the ROS 2 Code +^^^^^^^^^^^^^^^^^^^^^^^ + +To build ROS 2 you will need a Visual Studio Command Prompt (usually titled "x64 Native Tools Command Prompt for VS 2017" for bouncy and later or "x64 Native Tools Command Prompt for VS 2015" for ardent and earlier) running as Administrator. + +FastRTPS is bundled with the ROS 2 source and will always be built unless you put an ``AMENT_IGNORE`` file in the ``src\eProsima`` folder. + +To build the ``\dev\ros2`` folder tree: + +.. code-block:: + + > colcon build --merge-install + +Note, we're using ``--merge-install`` here to avoid a ``PATH`` variable that is too long at the end of the build. If you're adapting these instructions to build a smaller workspace then you might be able to use the default behavior which is isolated install, i.e. where each package is installed to a different folder. + +Note, if you are doing a debug build use ``python_d path\to\colcon_executable`` ``colcon``. +See `this page ` for more info on running Python code in debug builds on Windows. + +Testing and Running +^^^^^^^^^^^^^^^^^^^ + +Note that the first time you run any executable you will have to allow access to the network through a Windows Firewall popup. + +You can run the tests using this command: + +.. code-block:: + + > colcon test + +Afterwards you can get a summary of the tests using this command: + +.. code-block:: + + > colcon test-result + +To run the examples, first open a clean new ``cmd.exe`` and set up the workspace. +This is done by sourcing the ``local_setup.bat`` file, which will automatically set up the environment for any DDS vendors that support was built for. +Then execute the examples, e.g.: + +.. code-block:: + + > call install\local_setup.bat + > ros2 run demo_nodes_py talker + +In a separate shell you can do the same, but instead run the ``listener``\ : + +.. code-block:: + + > call install\local_setup.bat + > ros2 run demo_nodes_py listener + +For more explanations see the `Python Programming ` demo or `other tutorials `. + +Note: it is not recommended to build in the same cmd prompt that you've sourced the ``local_setup.bat``. + +Alternative DDS Sources +^^^^^^^^^^^^^^^^^^^^^^^ + +The demos will attempt to build against any detected DDS vendor. +The only bundled vendor is eProsima's Fast RTPS, which is included in the default set of sources for ROS 2.0. +To build for other vendors, make sure that your chosen DDS vendor(s) are exposed in your environment when you run the build. +If you would like to change which vendor is being used see: `Working with Multiple RMW Implementations ` + +Troubleshooting +--------------- + +CMake error setting modification time +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you run into the CMake error ``file INSTALL cannot set modification time on ...`` when installing files it is likely that an anti virus software or Windows Defender are interfering with the build. E.g. for Windows Defender you can list the workspace location to be excluded to prevent it from scanning those files. + +260 Character Path Limit +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: + + The input line is too long. + The syntax of the command is incorrect. + +You may see path length limit errors when building your own libraries, or maybe even in this guide as ROS2 matures. + +Run ``regedit.exe``\ , navigate to ``Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``\ , and set ``LongPathsEnabled`` to 0x00000001 (1). + +Hit the windows key and type ``Edit Group Policy``. Navigate to Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem. Right click ``Enable Win32 long paths``\ , click Edit. In the dialog, select Enabled and click OK. + +Close and open your terminal to reset the environment and try building again. + +CMake Packages Unable to Find asio, tinyxml2, tinyxml, or eigen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We've seen, but been unable to identify the root cause, that sometimes the chocolatey packages for ``asio``\ , ``tinyxml2``\ , etc. do not add important registry entries and that will cause CMake to be unable to find them when building ROS 2. + +It seems that uninstalling the chocolatey packages (with ``-n`` if the uninstall fails the first time) and then reinstalling them will fix the issue. + +patch.exe Opens a New Command Window and Asks for Administrator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This will also cause the build of packages which need to use patch to fail, even you allow it to use administrator rights. + +The solution, for now, is to make sure you're building in a Visual Studio command prompt which has been run as administrator. On some machines canceling the prompt without selecting "Yes" will also work. + +Extra stuff for Debug mode +-------------------------- + +If you want to be able to run all the tests in Debug mode, you'll need to install a few more things: + + +* To be able to extract the Python source tarball, you can use PeaZip: + +.. code-block:: + + > choco install -y peazip + + +* You'll also need SVN, since some of the Python source-build dependencies are checked out via SVN: + +.. code-block:: + + > choco install -y svn hg + + +* You'll need to quit and restart the command prompt after installing the above. +* Get and extract the Python 3.7.0 source from the ``tgz``\ : + + * https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz + * To keep these instructions concise, please extract it to ``C:\dev\Python-3.7.0`` + +* Now, build the Python source in debug mode from a Visual Studio command prompt: + +.. code-block:: + + > cd C:\dev\Python-3.7.0\PCbuild + > get_externals.bat + > build.bat -p x64 -d + + +* Finally, copy the build products into the Python37 installation directories, next to the Release-mode Python executable and DLL's: + +.. code-block:: + + > cd C:\dev\Python-3.7.0\PCbuild\amd64 + > copy python_d.exe C:\Python37 /Y + > copy python37_d.dll C:\Python37 /Y + > copy python3_d.dll C:\Python37 /Y + > copy python37_d.lib C:\Python37\libs /Y + > copy python3_d.lib C:\Python37\libs /Y + > for %I in (*_d.pyd) do copy %I C:\Python37\DLLs /Y + + +* Now, from a fresh command prompt, make sure that ``python_d`` works: + +.. code-block:: + + > python_d + > import _ctypes + + +* To create executables python scripts(.exe), python_d should be used to invoke colcon + +.. code-block:: + + > python_d path\to\colcon_executable build + + +* Hooray, you're done! diff --git a/Windows-Install-Binary.md b/Windows-Install-Binary.md deleted file mode 100644 index db359223ce0..00000000000 --- a/Windows-Install-Binary.md +++ /dev/null @@ -1,206 +0,0 @@ -# Installing ROS 2 on Windows - -This page explains how to install ROS 2 on Windows from a pre-built binary package. - -## System requirements -As of beta-2 only Windows 10 is supported. - -## Installing prerequisites - -### Install Chocolatey - -Chocolatey is a package manager for Windows, install it by following their installation instructions: - -https://chocolatey.org/ - -You'll use Chocolatey to install some other developer tools. - -### Install Python - -Open a Command Prompt and type the following to install Python via Chocolatey: - -``` -> choco install -y python -``` - -### Install OpenSSL - -Download an OpenSSL installer from [this page](https://slproweb.com/products/Win32OpenSSL.html). Scroll to the bottom of the page and download *Win64 OpenSSL v1.0.2*. Don't download the Win32 or Light versions. - -Run the installer with default parameters. Then, define environment variables (the following commands assume you used the default installation directory): - -- `setx -m OPENSSL_CONF C:\OpenSSL-Win64\bin\openssl.cfg` -- Add `C:\OpenSSL-Win64\bin\` to your PATH - -### Install Visual Studio -
-Install Visual Studio 2015 if using Ardent or earlier - -If you already have a paid version of Visual Studio 2015 (Professional, Enterprise), skip this step. - -Microsoft provides a free of charge version of Visual Studio 2015, named Community, which can be used to build applications that use ROS 2: - -https://www.visualstudio.com/vs/older-downloads/ - -Make sure that the Visual C++ features are installed. First choose 'Custom installation': - -![Custom installation](http://i.imgur.com/tUcOMOA.png) - -Next check Visual C++: - -![Visual C++](http://i.imgur.com/yWVEUkm.png) - -Ensure that the correct features will be installed: - -![Summary](http://i.imgur.com/VxdbA7G.png) -
- -
-Install Visual Studio 2017 if using Bouncy or a nightly - -If you already have a paid version of Visual Studio 2017 (Professional, Enterprise), skip this step. - -:warning: Visual Studio 2017 v15.8 seems to have a compiler bug preventing from building some ROS 2 packages. Please try installing an older version of Visual Studio 2017. - -Microsoft provides a free of charge version of Visual Studio 2017, named Community, which can be used to build applications that use ROS 2: - -https://visualstudio.microsoft.com/downloads/ - -Make sure that the Visual C++ features are installed. -An easy way to make sure they're installed is to select the `Desktop development with C++` workflow during the install. - -![Desktop development With C++](https://i.imgur.com/2h0IxCk.png) - -
- -### Install additional DDS implementations (optional) - -ROS 2 builds on top of DDS. -It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. - -The package you downloaded has been built with optional support for multiple vendors: eProsima FastRTPS, Adlink OpenSplice, and (as of ROS 2 Bouncy) RTI Connext as the middleware options. -Run-time support for eProsima's Fast RTPS is included bundled by default. -If you would like to use one of the other vendors you will need to install their software separately. - -#### Adlink OpenSplice - -If you want to use OpenSplice, you will need to [download the latest version](https://github.com/ADLINK-IST/opensplice/releases) (for ROS 2 Bouncy we require at least version 6.7.180404OSS-HDE-x86_64.win-vs2017). -For ROS 2 releases up to and including Ardent, extract it but do not do anything else at this point. -For ROS 2 releases later than Ardent, set the `OSPL_HOME` environment variable to the unpacked directory that contains the `release.bat` script. - -#### RTI Connext - -To use RTI Connext (available as of ROS 2 Bouncy) you will need to have obtained a license from RTI. - -You can install the Windows package of Connext version 5.3.1 provided by RTI from their [downloads page](https://www.rti.com/downloads). - -After installing, run RTI launcher and point it to your license file. - -Set the `NDDSHOME` environment variable: - -``` -set "NDDSHOME=C:\Program Files\rti_connext_dds-5.3.1" -``` - -If you want to install the Connext DDS-Security plugins please refer to [this page](Install-Connext-Security-Plugins.md) - -### Install OpenCV - -Some of the examples require OpenCV to be installed. - -You can download a precompiled version of OpenCV 3.4.1 from https://github.com/ros2/ros2/releases/download/opencv-archives/opencv-3.4.1-vc15.VS2017.zip - -Assuming you unpacked it to `C:\opencv`, type the following on a Command Prompt (requires Admin privileges): - -``` -setx -m OpenCV_DIR C:\opencv -``` - -Since you are using a precompiled ROS version, we have to tell it where to find the OpenCV libraries. You have to extend the `PATH` variable to `c:\opencv\x64\vc15\bin` - -#### In ardent and earlier - -These releases used OpenCV 2. You can download a precompiled version of OpenCV 2.4.13.2 from https://github.com/ros2/ros2/releases/download/release-beta2/opencv-2.4.13.2-vc14.VS2015.zip - -Since you are using a precompiled ROS version, we have to tell it where to find the OpenCV libraries. Assuming you were extracting OpenCV to `c:\` you have to extend the `PATH` variable to `c:\opencv-2.4.13.2-vc14.VS2015\x64\vc14\bin` - -### Install dependencies -There are a few dependencies not available in the Chocolatey package database. In order to ease the manual installation process, we provide the necessary Chocolatey packages. - -As some chocolatey packages rely on it, we start by installing CMake - -``` -> choco install -y cmake -``` - -You will need to append the CMake bin folder `C:\Program Files\CMake\bin` to the PATH (you can do this by clicking the Windows icon, typing "Environment Variables", then clicking on "Edit the system environment variables". -In the resulting dialog, click "Environment Variables", the click "Path" on the bottom pane, then click "Edit" and add the path). - -Please download these packages from [this](https://github.com/ros2/choco-packages/releases/latest) GitHub repository. - * asio.1.12.1.nupkg - * eigen-3.3.4.nupkg - * tinyxml-usestl.2.6.2.nupkg - * tinyxml2.6.0.0.nupkg - -Once these packages are downloaded, open an administrative shell and execute the following command: - -``` -> choco install -y -s asio eigen tinyxml-usestl tinyxml2 -``` - -Please replace `` with the folder you downloaded the packages to. - -You must also install some python dependencies for command-line tools: - -``` -python -m pip install -U catkin_pkg empy pyparsing pyyaml setuptools -``` - -## Downloading ROS 2 - -* Go the releases page: https://github.com/ros2/ros2/releases -* Download the latest package for Windows, e.g., `ros2-package-windows-AMD64.zip`. - * Notes: - * there may be more than one binary download option which might cause the file name to differ. - * [ROS Bouncy only] To download the ROS 2 debug libraries you'll need to download `ros2-bouncy-windows-Debug-AMD64.zip` -* Unpack the zip file somewhere (we'll assume `C:\dev\ros2`). - * Note (Ardent and earlier): There seems to be an issue where extracting the zip file with 7zip causes RViz to crash on startup. Extract the zip file using the Windows explorer to prevent this. - -## Set up the ROS 2 environment - -Start a command shell and source the ROS 2 setup file to set up the workspace: - -``` -> call C:\dev\ros2\local_setup.bat -``` - -For ROS 2 releases up to and including Ardent, if you downloaded a release with OpenSplice support you must additionally source the OpenSplice setup file manually (this is done automatically for ROS 2 releases later than Ardent; this step can be skipped). -It is normal that the previous command, if nothing else went wrong, outputs "The system cannot find the path specified." exactly once. -Only do this step **after** you have sourced the ROS 2 setup file: - -``` -> call "C:\opensplice67\HDE\x86_64.win64\release.bat" -``` - -## Try some examples - -In a command shell, set up the ROS 2 environment as described above and then run a `talker`: - -``` -> ros2 run demo_nodes_cpp talker -``` - -Start another command shell and run a `listener`: - -``` -> ros2 run demo_nodes_py listener -``` - -You should see the `talker` saying that it's `Publishing` messages and the `listener` saying `I heard` those messages. -Hooray! - -If you have installed support for an optional vendor, see [this page](Working-with-multiple-RMW-implementations.md) for details on how to use that vendor. - -### Troubleshooting -* If at one point your example would not start because of missing dll's, please verify that all libraries from external dependencies such as OpenCV are located inside your `PATH` variable. -* If you forget to call the `local_setup.bat` file from your terminal, the demo programs will most likely crash immediately. diff --git a/Windows-Install-Binary.rst b/Windows-Install-Binary.rst new file mode 100644 index 00000000000..8512e39b684 --- /dev/null +++ b/Windows-Install-Binary.rst @@ -0,0 +1,245 @@ + +Installing ROS 2 on Windows +=========================== + +This page explains how to install ROS 2 on Windows from a pre-built binary package. + +System requirements +------------------- + +As of beta-2 only Windows 10 is supported. + +Installing prerequisites +------------------------ + +Install Chocolatey +^^^^^^^^^^^^^^^^^^ + +Chocolatey is a package manager for Windows, install it by following their installation instructions: + +https://chocolatey.org/ + +You'll use Chocolatey to install some other developer tools. + +Install Python +^^^^^^^^^^^^^^ + +Open a Command Prompt and type the following to install Python via Chocolatey: + +.. code-block:: + + > choco install -y python + +Install OpenSSL +^^^^^^^^^^^^^^^ + +Download an OpenSSL installer from `this page `__. Scroll to the bottom of the page and download *Win64 OpenSSL v1.0.2*. Don't download the Win32 or Light versions. + +Run the installer with default parameters. Then, define environment variables (the following commands assume you used the default installation directory): + + +* ``setx -m OPENSSL_CONF C:\OpenSSL-Win64\bin\openssl.cfg`` +* Add ``C:\OpenSSL-Win64\bin\`` to your PATH + +Install Visual Studio +^^^^^^^^^^^^^^^^^^^^^ + + +.. raw:: html + +
+ Install Visual Studio 2015 if using Ardent or earlier + + If you already have a paid version of Visual Studio 2015 (Professional, Enterprise), skip this step. + + Microsoft provides a free of charge version of Visual Studio 2015, named Community, which can be used to build applications that use ROS 2: + + https://www.visualstudio.com/vs/older-downloads/ + + Make sure that the Visual C++ features are installed. First choose 'Custom installation': + + ![Custom installation](http://i.imgur.com/tUcOMOA.png) + + Next check Visual C++: + + ![Visual C++](http://i.imgur.com/yWVEUkm.png) + + Ensure that the correct features will be installed: + + ![Summary](http://i.imgur.com/VxdbA7G.png) +
+ + + +.. raw:: html + +
+ Install Visual Studio 2017 if using Bouncy or a nightly + + If you already have a paid version of Visual Studio 2017 (Professional, Enterprise), skip this step. + + :warning: Visual Studio 2017 v15.8 seems to have a compiler bug preventing from building some ROS 2 packages. Please try installing an older version of Visual Studio 2017. + + Microsoft provides a free of charge version of Visual Studio 2017, named Community, which can be used to build applications that use ROS 2: + + https://visualstudio.microsoft.com/downloads/ + + Make sure that the Visual C++ features are installed. + An easy way to make sure they're installed is to select the `Desktop development with C++` workflow during the install. + + ![Desktop development With C++](https://i.imgur.com/2h0IxCk.png) + +
+ + +Install additional DDS implementations (optional) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ROS 2 builds on top of DDS. +It is compatible with multiple DDS or RTPS (the DDS wire protocol) vendors. + +The package you downloaded has been built with optional support for multiple vendors: eProsima FastRTPS, Adlink OpenSplice, and (as of ROS 2 Bouncy) RTI Connext as the middleware options. +Run-time support for eProsima's Fast RTPS is included bundled by default. +If you would like to use one of the other vendors you will need to install their software separately. + +Adlink OpenSplice +~~~~~~~~~~~~~~~~~ + +If you want to use OpenSplice, you will need to `download the latest version `__ (for ROS 2 Bouncy we require at least version 6.7.180404OSS-HDE-x86_64.win-vs2017). +For ROS 2 releases up to and including Ardent, extract it but do not do anything else at this point. +For ROS 2 releases later than Ardent, set the ``OSPL_HOME`` environment variable to the unpacked directory that contains the ``release.bat`` script. + +RTI Connext +~~~~~~~~~~~ + +To use RTI Connext (available as of ROS 2 Bouncy) you will need to have obtained a license from RTI. + +You can install the Windows package of Connext version 5.3.1 provided by RTI from their `downloads page `__. + +After installing, run RTI launcher and point it to your license file. + +Set the ``NDDSHOME`` environment variable: + +.. code-block:: + + set "NDDSHOME=C:\Program Files\rti_connext_dds-5.3.1" + +If you want to install the Connext DDS-Security plugins please refer to `this page ` + +Install OpenCV +^^^^^^^^^^^^^^ + +Some of the examples require OpenCV to be installed. + +You can download a precompiled version of OpenCV 3.4.1 from https://github.com/ros2/ros2/releases/download/opencv-archives/opencv-3.4.1-vc15.VS2017.zip + +Assuming you unpacked it to ``C:\opencv``\ , type the following on a Command Prompt (requires Admin privileges): + +.. code-block:: + + setx -m OpenCV_DIR C:\opencv + +Since you are using a precompiled ROS version, we have to tell it where to find the OpenCV libraries. You have to extend the ``PATH`` variable to ``c:\opencv\x64\vc15\bin`` + +In ardent and earlier +~~~~~~~~~~~~~~~~~~~~~ + +These releases used OpenCV 2. You can download a precompiled version of OpenCV 2.4.13.2 from https://github.com/ros2/ros2/releases/download/release-beta2/opencv-2.4.13.2-vc14.VS2015.zip + +Since you are using a precompiled ROS version, we have to tell it where to find the OpenCV libraries. Assuming you were extracting OpenCV to ``c:\`` you have to extend the ``PATH`` variable to ``c:\opencv-2.4.13.2-vc14.VS2015\x64\vc14\bin`` + +Install dependencies +^^^^^^^^^^^^^^^^^^^^ + +There are a few dependencies not available in the Chocolatey package database. In order to ease the manual installation process, we provide the necessary Chocolatey packages. + +As some chocolatey packages rely on it, we start by installing CMake + +.. code-block:: + + > choco install -y cmake + +You will need to append the CMake bin folder ``C:\Program Files\CMake\bin`` to the PATH (you can do this by clicking the Windows icon, typing "Environment Variables", then clicking on "Edit the system environment variables". +In the resulting dialog, click "Environment Variables", the click "Path" on the bottom pane, then click "Edit" and add the path). + +Please download these packages from `this `__ GitHub repository. + + +* asio.1.12.1.nupkg +* eigen-3.3.4.nupkg +* tinyxml-usestl.2.6.2.nupkg +* tinyxml2.6.0.0.nupkg + +Once these packages are downloaded, open an administrative shell and execute the following command: + +.. code-block:: + + > choco install -y -s asio eigen tinyxml-usestl tinyxml2 + +Please replace ```` with the folder you downloaded the packages to. + +You must also install some python dependencies for command-line tools: + +.. code-block:: + + python -m pip install -U catkin_pkg empy pyparsing pyyaml setuptools + +Downloading ROS 2 +----------------- + + +* Go the releases page: https://github.com/ros2/ros2/releases +* Download the latest package for Windows, e.g., ``ros2-package-windows-AMD64.zip``. + + * Notes: + + * there may be more than one binary download option which might cause the file name to differ. + * [ROS Bouncy only] To download the ROS 2 debug libraries you'll need to download ``ros2-bouncy-windows-Debug-AMD64.zip`` + +* Unpack the zip file somewhere (we'll assume ``C:\dev\ros2``\ ). + + * Note (Ardent and earlier): There seems to be an issue where extracting the zip file with 7zip causes RViz to crash on startup. Extract the zip file using the Windows explorer to prevent this. + +Set up the ROS 2 environment +---------------------------- + +Start a command shell and source the ROS 2 setup file to set up the workspace: + +.. code-block:: + + > call C:\dev\ros2\local_setup.bat + +For ROS 2 releases up to and including Ardent, if you downloaded a release with OpenSplice support you must additionally source the OpenSplice setup file manually (this is done automatically for ROS 2 releases later than Ardent; this step can be skipped). +It is normal that the previous command, if nothing else went wrong, outputs "The system cannot find the path specified." exactly once. +Only do this step **after** you have sourced the ROS 2 setup file: + +.. code-block:: + + > call "C:\opensplice67\HDE\x86_64.win64\release.bat" + +Try some examples +----------------- + +In a command shell, set up the ROS 2 environment as described above and then run a ``talker``\ : + +.. code-block:: + + > ros2 run demo_nodes_cpp talker + +Start another command shell and run a ``listener``\ : + +.. code-block:: + + > ros2 run demo_nodes_py listener + +You should see the ``talker`` saying that it's ``Publishing`` messages and the ``listener`` saying ``I heard`` those messages. +Hooray! + +If you have installed support for an optional vendor, see `this page ` for details on how to use that vendor. + +Troubleshooting +^^^^^^^^^^^^^^^ + + +* If at one point your example would not start because of missing dll's, please verify that all libraries from external dependencies such as OpenCV are located inside your ``PATH`` variable. +* If you forget to call the ``local_setup.bat`` file from your terminal, the demo programs will most likely crash immediately. diff --git a/Working-with-multiple-RMW-implementations.md b/Working-with-multiple-RMW-implementations.md deleted file mode 100644 index be380713eee..00000000000 --- a/Working-with-multiple-RMW-implementations.md +++ /dev/null @@ -1,85 +0,0 @@ -# Working with multiple ROS 2 middleware implementations -This page explains the default RMW implementation and how to specify an alternative. - -## Pre-requisites -You should have already read the [DDS and ROS middleware implementations](DDS-and-ROS-middleware-implementations.md) page. - -## Multiple RMW implementations - -The current ROS 2 binary releases have built-in support for several RMW implementations out of the box (Fast RTPS, RTI Connext Pro, and ADLink OpenSplice at the time of writing), but only Fast RTPS (the default) works without any additional installation steps, because it is the only one we distribute with our binary packages. - -Others like OpenSplice or Connext can be enabled by installing additional packages, but without having to rebuild anything or replace any existing packages. - -Also, a ROS 2 workspace that has been built from source may build and install multiple RMW implementations simultaneously. -While the core ROS 2 code is being compiled, any RMW implementation that is found will be built if the relevant DDS/RTPS implementation has been installed properly and the relevant environment variables have been configured. -For example, if the code for the [RMW package for RTI Connext](https://github.com/ros2/rmw_connext_cpp) is in the workspace, it will be built if an installation of RTI's Connext Pro can also be found. -For many cases you will find that nodes using different RMW implementations are able to communicate, however this is not true under all circumstances. -A list of supported inter-vendor communication configurations is forthcoming. - -## Default RMW implementation - -If a ROS 2 workspace has multiple RMW implementations, the default RMW implementation is currently selected as Fast RTPS if it's available. -If the Fast RTPS RMW implementation is not installed, the RMW implementation with the first RMW implementation identifier in alphabetical order will be used. -The implementation identifier is the name of the ROS package that provides the RMW implementation, e.g. `rmw_fastrtps_cpp`. -For example, if both `rmw_opensplice_cpp` and `rmw_connext_cpp` ROS packages are installed, `rmw_connext_cpp` would be the default. -If `rmw_fastrtps_cpp` is ever installed, it would be the default. -See below for how to specify which RMW implementation is to be used when running the ROS 2 examples. - -## Specifying RMW implementations - ---- - -To have multiple RMW implementations available for use you must have installed our binaries and any additional dependencies for specific RMW implementations, or built ROS 2 from source with multiple RMW implementations in the workspace (they are included by default) and their dependencies are met (for example see [the Linux install instructions](Linux-Development-Setup.md#install-more-dds-implementations-optional)). - ---- - -Starting in Beta 2 and above both C++ and Python nodes support an environment variable `RMW_IMPLEMENTATION`. -To choose a different RMW implemenation you can set the environment variable `RMW_IMPLEMENTATION` to a specific implementation identifier. - -To run the talker demo using the C++ and listener using python with the RMW implementation for connext: - -*Bash* -```bash -RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_cpp talker - -# Run in another terminal -RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_py listener -``` - -*Windows cmd.exe* -```bat -set RMW_IMPLEMENTATION=rmw_connext_cpp -ros2 run demo_nodes_cpp talker - -REM run in another terminal -set RMW_IMPLEMENTATION=rmw_connext_cpp -ros2 run demo_nodes_py listener -``` - -## Adding RMW implementations to your workspace - -Suppose that you have built your ROS 2 workspace with only Fast RTPS installed and therefore only the Fast RTPS RMW implementation built. -The last time your workspace was built, any other RMW implementation packages, `rmw_connext_cpp` for example, were probably unable to find installations of the relevant DDS implementations. -If you then install an additional DDS implementation, Connext for example, you will need to re-trigger the check for a Connext installation that occurs when the Connext RMW implementation is being built. -You can do this by specifying the `--force-cmake-configure` flag on your next workspace build, and you should see that the RMW implementation package then gets built for the newly installed DDS implementation. - -It is possible to run into a problem when "rebuilding" the workspace with an additional RMW implementation using the `--force-cmake-configure` option where the build complains about the default RMW implementation changing. -To resolve this, you can either set the default implementation to what is was before with the `RMW_IMPLEMENTATION` CMake argument or you can delete the build folder for packages that complain and continue the build with `--start-with `. - -## Troubleshooting - -### Ensuring use of a particular RMW implementation - -#### ROS 2 Ardent and later - -If the `RMW_IMPLEMENTATION` environment variable is set to an RMW implementation for which support is not installed, you will see an error message similar to the following if you have only one implementation installed: -``` -Expected RMW implementation identifier of 'rmw_connext_cpp' but instead found 'rmw_fastrtps_cpp', exiting with 102. -``` - -If you have support for multiple RMW implementations installed and you request use of one that is not installed, you will see something similar to: -``` -Error getting RMW implementation identifier / RMW implementation not installed (expected identifier of 'rmw_connext_cpp'), exiting with 1. -``` - -If this occurs, double check that your ROS 2 installation includes support for the RMW implementation that you have specified in the `RMW_IMPLEMENTATION` environment variable. diff --git a/Working-with-multiple-RMW-implementations.rst b/Working-with-multiple-RMW-implementations.rst new file mode 100644 index 00000000000..17a5229f559 --- /dev/null +++ b/Working-with-multiple-RMW-implementations.rst @@ -0,0 +1,101 @@ + +Working with multiple ROS 2 middleware implementations +====================================================== + +This page explains the default RMW implementation and how to specify an alternative. + +Pre-requisites +-------------- + +You should have already read the `DDS and ROS middleware implementations ` page. + +Multiple RMW implementations +---------------------------- + +The current ROS 2 binary releases have built-in support for several RMW implementations out of the box (Fast RTPS, RTI Connext Pro, and ADLink OpenSplice at the time of writing), but only Fast RTPS (the default) works without any additional installation steps, because it is the only one we distribute with our binary packages. + +Others like OpenSplice or Connext can be enabled by installing additional packages, but without having to rebuild anything or replace any existing packages. + +Also, a ROS 2 workspace that has been built from source may build and install multiple RMW implementations simultaneously. +While the core ROS 2 code is being compiled, any RMW implementation that is found will be built if the relevant DDS/RTPS implementation has been installed properly and the relevant environment variables have been configured. +For example, if the code for the `RMW package for RTI Connext `__ is in the workspace, it will be built if an installation of RTI's Connext Pro can also be found. +For many cases you will find that nodes using different RMW implementations are able to communicate, however this is not true under all circumstances. +A list of supported inter-vendor communication configurations is forthcoming. + +Default RMW implementation +-------------------------- + +If a ROS 2 workspace has multiple RMW implementations, the default RMW implementation is currently selected as Fast RTPS if it's available. +If the Fast RTPS RMW implementation is not installed, the RMW implementation with the first RMW implementation identifier in alphabetical order will be used. +The implementation identifier is the name of the ROS package that provides the RMW implementation, e.g. ``rmw_fastrtps_cpp``. +For example, if both ``rmw_opensplice_cpp`` and ``rmw_connext_cpp`` ROS packages are installed, ``rmw_connext_cpp`` would be the default. +If ``rmw_fastrtps_cpp`` is ever installed, it would be the default. +See below for how to specify which RMW implementation is to be used when running the ROS 2 examples. + +Specifying RMW implementations +------------------------------ + +---- + +To have multiple RMW implementations available for use you must have installed our binaries and any additional dependencies for specific RMW implementations, or built ROS 2 from source with multiple RMW implementations in the workspace (they are included by default) and their dependencies are met (for example see `the Linux install instructions `_\ ). + +---- + +Starting in Beta 2 and above both C++ and Python nodes support an environment variable ``RMW_IMPLEMENTATION``. +To choose a different RMW implemenation you can set the environment variable ``RMW_IMPLEMENTATION`` to a specific implementation identifier. + +To run the talker demo using the C++ and listener using python with the RMW implementation for connext: + +*Bash* + +.. code-block:: bash + + RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_cpp talker + + # Run in another terminal + RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run demo_nodes_py listener + +*Windows cmd.exe* + +.. code-block:: bat + + set RMW_IMPLEMENTATION=rmw_connext_cpp + ros2 run demo_nodes_cpp talker + + REM run in another terminal + set RMW_IMPLEMENTATION=rmw_connext_cpp + ros2 run demo_nodes_py listener + +Adding RMW implementations to your workspace +-------------------------------------------- + +Suppose that you have built your ROS 2 workspace with only Fast RTPS installed and therefore only the Fast RTPS RMW implementation built. +The last time your workspace was built, any other RMW implementation packages, ``rmw_connext_cpp`` for example, were probably unable to find installations of the relevant DDS implementations. +If you then install an additional DDS implementation, Connext for example, you will need to re-trigger the check for a Connext installation that occurs when the Connext RMW implementation is being built. +You can do this by specifying the ``--force-cmake-configure`` flag on your next workspace build, and you should see that the RMW implementation package then gets built for the newly installed DDS implementation. + +It is possible to run into a problem when "rebuilding" the workspace with an additional RMW implementation using the ``--force-cmake-configure`` option where the build complains about the default RMW implementation changing. +To resolve this, you can either set the default implementation to what is was before with the ``RMW_IMPLEMENTATION`` CMake argument or you can delete the build folder for packages that complain and continue the build with ``--start-with ``. + +Troubleshooting +--------------- + +Ensuring use of a particular RMW implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ROS 2 Ardent and later +~~~~~~~~~~~~~~~~~~~~~~ + +If the ``RMW_IMPLEMENTATION`` environment variable is set to an RMW implementation for which support is not installed, you will see an error message similar to the following if you have only one implementation installed: + +.. code-block:: + + Expected RMW implementation identifier of 'rmw_connext_cpp' but instead found 'rmw_fastrtps_cpp', exiting with 102. + +If you have support for multiple RMW implementations installed and you request use of one that is not installed, you will see something similar to: + +.. code-block:: + + Error getting RMW implementation identifier / RMW implementation not installed (expected identifier of 'rmw_connext_cpp'), exiting with 1. + +If this occurs, double check that your ROS 2 installation includes support for the RMW implementation that you have specified in the ``RMW_IMPLEMENTATION`` environment variable. diff --git a/catment.md b/catment.md deleted file mode 100644 index adf9c28e5fa..00000000000 --- a/catment.md +++ /dev/null @@ -1,235 +0,0 @@ -# catment: On the mixing of ament and catkin - -**All that follows is experimental and speculative.** - -* [Background](#background) -* [Postulates](#postulates) -* [Use cases, with experimental implementations](#use-cases-with-experimental-implementations) - -## Background - -There once was a thing called `rosbuild`. -Then came a thing called `catkin`, which largely replaced `rosbuild`. -Recently introduced is a thing called `ament`, which may one day replace `catkin`. - -All three tools can be considered "meta-build systems." -They sit atop other build systems (e.g., CMake, Python setuptools) and provide extra functionality that's intended to make those build systems easier to use, especially when managing dependencies across multiple packages and when building multiple packages in a single workspace. - -Each of these meta-build systems does two things: - -1. Add API to the underlying build system (e.g,. CMake) that can be used to simplify common tasks (e.g., supplying all the flags exported by depended-upon packages when building an executable). -There are usually hooks to allow injection of extra API by packages outside of the core meta-build system. - - * `rosbuild`: `mk/cmake.mk`, `rosbuild_init()`, `rosbuild_add_executable()`, etc. - * `catkin`: `catkin_package()`, `catkin_install_python()`, etc. - * `ament`: `ament_target_dependencies()`, `ament_export_dependencies()`, `ament_package()`, etc. - -1. Provide a tool that can be used to iterate in dependency order over a workspace full of packages, building and perhaps installing each one. - - * `rosbuild`: `rosmake` - * `catkin`: `catkin build`, `catkin_make`, `catkin_make_isolated`, etc. - * `ament`: `ament build` - -The common thread that ties all of these systems together is the division of the code into **packages**, with each package containing a manifest file (`manifest.xml` or `package.xml`). -This manifest is required (with some exceptions) for both parts of the meta-build system (API and building tool) to function. - -## Postulates - -1. **While we usually consider the two aspects of a meta-build system to be coupled, they needn't be.** -The API used inside a package and the tool that iterates over the packages can be considered largely independent, with the package manifest forming the interface between them. -There's no reason in principle why, for example, `rosmake` couldn't be modified to iterate over a workspace filled with `catkin` packages, stepping into them in dependency order and doing the usual `mkdir build; cd build; cmake ..; make install` routine for each one (with appropriate flags passed to `cmake` and `make`). -1. **The effort required to migrate from one meta-build system to another should be minimized.** -The mass migration from `rosbuild` to `catkin` was difficult and remains a sore point for many in the community. -While it's reasonable to ask developers to make changes in exchange for getting access to new functionality, the changes that are required should be as small as possible without sacrificing the effectiveness of the new system. -This is especially true when the old system is in widespread use. - - 1. Corollary: **Migration to a new meta-build system should not be required without a very good reason.** - If a developer doesn't want the functionality offered by the new system, then she shouldn't be coerced into migrating from the old system unless there's something irrevocably broken about the old system (e.g., `rosbuild`'s in-source build pattern and lack of an "install" step). - -1. **Interoperability is a good thing.** -Whenever possible (not all combinations will be practical), developers should be able to mix and match meta-build systems, including mixing their different aspects (i.e., use the building tool from one system and the API from another). -Such mixing and matching is especially important when developers want to combine a large existing code base using one meta-build system (e.g., ROS with `catkin`) with new libraries and tools offered by a code base using another meta-build system (e.g., ROS2 with `ament`). -Ideally that kind of combination can be done without requiring changes to the API used by either code base and without telling the developer which builder tool to use. - - 1. Corollary: **Workspaces needn't be homogeneous.** - There's no reason that we shouldn't be able to freely mix, say, `catkin` and `ament` packages in one workspace, with dependencies going in both directions, so long as the builder tool in use knows how to build them both. - The primary interface between packages (at least, CMake-controlled packages) is their CMake configuration file. - So long as that configuration file follows the standard protocol (setting `foo_LIBRARIES`, etc.), then it shouldn't matter who wrote the file. - It could be auto-generated by `catkin` or `ament`, or even manually crafted by a developer who wants to use plain CMake in her package, but still have that package depended-upon by `catkin` or `ament` packages. - -## Use cases, with experimental implementations - -### Adding ROS packages to a ROS2 workspace and building with `ament build` - -Let's say that you want to add some existing ROS packages to your ROS2 workspace and don't want to migrate the ROS packages from `catkin` to `ament` (or vice versa). Here are two patches that let you do that: - -* [ament_package](https://github.com/ament/ament_package/compare/catkin?expand=1): -Add support for format 1 package manifests, instead of requiring format 2. -This change isn't strictly related to `catkin` vs. `ament`, because format 2 has been around for a while and `catkin` supports it, so developers could already update their manifests to format 2. -But there's a ton of ROS code out there that uses format 1, so we should support it. -This implementation could be improved, e.g., by reasoning over the various flavors of depend tags and how they differ between formats 1 and 2. -* [ament_tools](https://github.com/ament/ament_tools/compare/catkin?expand=1): -Add a new `catkin` build type to `ament`. -This implementation just treats `catkin` packages the same as plain `cmake` packages, which seems to work fine. -It could be made more sophisticated. - -Example usage: - -1. Get the ROS2 code as usual, using the branches mentioned above. -1. Add to your workspace some `catkin` ROS packages, ensuring that all of their dependencies are satisfied (either also present in the workspace or installed elsewhere with appropriate setup shell files sourced). -1. Build as usual (e.g., `./src/ament/ament_tools/scripts/ament.by build`). - -Voila: your existing code isn't suddenly broken just because there's a new builder tool in use. - -#### Variation: Building ROS packages with `ament build` - -Let's say that you love the new `ament` tool and want to use it to build your existing ROS packages that use `catkin` internally. -Here's an example of how to do that, by doing a minimal installation of `ament` and then using it to build a workspace full of ROS `catkin` packages: - -``` -mkdir -p ~/ament_ws/src -cd ~/ament_ws/src -git clone https://github.com/osrf/osrf_pycommon.git -git clone https://github.com/ament/ament_package.git -cd ament_package -git checkout catkin -cd .. -git clone https://github.com/ament/ament_tools.git -cd ament_tools -git checkout catkin -cd ../.. - ./src/ament_tools/scripts/ament.py build -``` - -Now build the ROS packages: -``` -. $HOME/ament_ws/install/setup.bash -cd ~/ros_catkin_ws -ament build -``` - -Voila: you used the `ament` build tool to build your `catkin` packages, without having to migrate them. - -#### Variation: Using the `catkin` API in a ROS2 package - -Let's say that you're building on top of ROS2, which internally uses the `ament` API, and you want to add a new package using the `catkin` API. - -To make this work, we need a Python3 installation of `catkin` (the binary debians use Python2.7). -Here's an example of doing that, installing to `$HOME/catkin`: - -``` -# install catkin_pkg -git clone https://github.com/ros-infrastructure/catkin_pkg.git -cd catkin_pkg -git checkout ament -python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb -# install catkin -git clone https://github.com/ros/catkin.git -cd catkin -git checkout ament -mkdir build -cd build -PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 -make install -``` - -To use that version of catkin, you just need to source the `$HOME/catkin/setup.bash` file. - -Let's assume that you have the usual ROS2 workspace in `~/ros2_ws`, and that you're on the `catkin` branches in `ament_package` and `ament_tools`. -Add to that workspace the `image_tools_catkin` package from https://github.com/gerkey/catment. -It's a simple port of the ROS2 `image_tools` package, taking it from the `ament` API to the `catkin` API. -To build it: - -``` -cd ~/ros2_ws -. $HOME/catkin/setup.bash -./src/ament/ament_tools/scripts/ament.py build -``` - -Voila: when adding new packages atop ROS2, you're free to choose which CMake API you prefer inside your package. - -* **Caveat**: I had to comment out the use of `CATKIN_DEPENDS` inside `catkin_package()`, because somewhere somebody was getting upset that things like `rclcpp` aren't `catkin` packages. -That constraint needs to be relaxed somehow. -* **TODO**: The same demo but with a `ament` package that depends on a `catkin` package (this is easy). -* **TODO**: The same demo but with a package that has a vanilla `CMakeLists.txt` that uses neither `ament` nor `catkin`, and provides a manually generated `fooConfig.cmake` file that exports the right stuff to make it look the same to outsiders. - -### Building ROS2 packages with `catkin_make_isolated` - -Let's say that you're already familiar with ROS and `catkin` and that you're excited to try ROS2, but that you're not in the mood to learn about `ament`. -You'd rather stick to what you know, such as using `catkin_make_isolated` to build everything. -Here is a patch that allows you to do that: - -* [catkin](https://github.com/ros/catkin/compare/ament?expand=1): -Add support for packages that declare themselves to have a build type of `ament_*`. -This implementation calls out to `ament` to build each such package. -While `ament_cmake` packages can be treated as plain `cmake` packages (as we did when adding `catkin` support to `ament`), `ament_python` packages require some gnarly invocations of Python. -Instead of trying to replicate that logic in `catkin`, it's easier to just let `ament` handle it. -Also in this patch, we add the `buildtool_export_depend` packages to the set that are considered when building. -* [catkin_pkg](https://github.com/ros-infrastructure/catkin_pkg/compare/ament?expand=1): -Also in this patch, we add the `buildtool_export_depend` packages to the set that are considered when computing the topological order. - -Because we're going to call out to `ament build`, we will also need a minimal installation of `ament`, as did in a previous example: - -``` -mkdir -p ~/ament_ws/src -cd ~/ament_ws/src -git clone https://github.com/osrf/osrf_pycommon.git -git clone https://github.com/ament/ament_package.git -cd ament_package -git checkout catkin -cd .. -git clone https://github.com/ament/ament_tools.git -cd ament_tools -git checkout catkin -cd ../.. - ./src/ament_tools/scripts/ament.py build -``` - -Then we need to install the modified version of catkin somewhere: - -``` -# install catkin_pkg -git clone https://github.com/ros-infrastructure/catkin_pkg.git -cd catkin_pkg -git checkout ament -python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb -# install catkin -git clone https://github.com/ros/catkin.git -cd catkin -git checkout ament -mkdir build -cd build -PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 -make install -``` - -Now build the ROS2 packages: -``` -. $HOME/catkin/setup.bash -. $HOME/ament_ws/install/setup.bash -cd ~/ros2_ws -touch src/eProsima/AMENT_IGNORE -PYTHONPATH=$PYTHONPATH:/home/gerkey/ros2_ws_catkin/install_isolated/lib/python3.5/site-packages catkin_make_isolated --install -``` - -Voila: you've built ROS2 using the tools that you're familiar with. - -* **Caveat**: we're ignoring the `eProsima` packages in the workspace because they lack `package.xml` files, which means that `catkin` can't see them. -`ament` has some heuristics for handling such packages. -Options: backport those heuristics to `catkin`; switch to installing non-`package.xml`-containing packages outside of the workspace; or just add a `package.xml` to each of those packages (e.g., in our own fork). - -### Combining all of ROS and ROS2 in one workspace and building it (TODO) - -This step will require sorting out some things, including at least: - -* Package name conflicts. -We currently have ROS2 versions of ROS message packages, as well as some stuff in `geometry2`. -Either the functionality needs to be merged into one package that can support both systems, or the new versions need different names. -* Message generation. -ROS and ROS2 have different message generation steps, the output of which might or not might conflict. -Something sort of sophisticated needs to be done to allow generation of all the right artifacts from a single message package (or, as indicated above, the new message packages need different name). - -### Using `bloom` to release `ament` packages (TODO) - -It seems like `bloom` ought be able to release packages that use the `ament` CMake API, and that the resulting releases should be able to be built on the farm. -We can make changes to `bloom` and `ros_buildfarm` as needed to enable this use case. \ No newline at end of file diff --git a/catment.rst b/catment.rst new file mode 100644 index 00000000000..82c96a9d136 --- /dev/null +++ b/catment.rst @@ -0,0 +1,265 @@ + +catment: On the mixing of ament and catkin +========================================== + +**All that follows is experimental and speculative.** + + +* `Background <#background>` +* `Postulates <#postulates>` +* `Use cases, with experimental implementations <#use-cases-with-experimental-implementations>` + +Background +---------- + +There once was a thing called ``rosbuild``. +Then came a thing called ``catkin``\ , which largely replaced ``rosbuild``. +Recently introduced is a thing called ``ament``\ , which may one day replace ``catkin``. + +All three tools can be considered "meta-build systems." +They sit atop other build systems (e.g., CMake, Python setuptools) and provide extra functionality that's intended to make those build systems easier to use, especially when managing dependencies across multiple packages and when building multiple packages in a single workspace. + +Each of these meta-build systems does two things: + + +#. + Add API to the underlying build system (e.g,. CMake) that can be used to simplify common tasks (e.g., supplying all the flags exported by depended-upon packages when building an executable). + There are usually hooks to allow injection of extra API by packages outside of the core meta-build system. + + + * ``rosbuild``\ : ``mk/cmake.mk``\ , ``rosbuild_init()``\ , ``rosbuild_add_executable()``\ , etc. + * ``catkin``\ : ``catkin_package()``\ , ``catkin_install_python()``\ , etc. + * ``ament``\ : ``ament_target_dependencies()``\ , ``ament_export_dependencies()``\ , ``ament_package()``\ , etc. + +#. + Provide a tool that can be used to iterate in dependency order over a workspace full of packages, building and perhaps installing each one. + + + * ``rosbuild``\ : ``rosmake`` + * ``catkin``\ : ``catkin build``\ , ``catkin_make``\ , ``catkin_make_isolated``\ , etc. + * ``ament``\ : ``ament build`` + +The common thread that ties all of these systems together is the division of the code into **packages**\ , with each package containing a manifest file (\ ``manifest.xml`` or ``package.xml``\ ). +This manifest is required (with some exceptions) for both parts of the meta-build system (API and building tool) to function. + +Postulates +---------- + + +#. **While we usually consider the two aspects of a meta-build system to be coupled, they needn't be.** + The API used inside a package and the tool that iterates over the packages can be considered largely independent, with the package manifest forming the interface between them. + There's no reason in principle why, for example, ``rosmake`` couldn't be modified to iterate over a workspace filled with ``catkin`` packages, stepping into them in dependency order and doing the usual ``mkdir build; cd build; cmake ..; make install`` routine for each one (with appropriate flags passed to ``cmake`` and ``make``\ ). +#. + **The effort required to migrate from one meta-build system to another should be minimized.** + The mass migration from ``rosbuild`` to ``catkin`` was difficult and remains a sore point for many in the community. + While it's reasonable to ask developers to make changes in exchange for getting access to new functionality, the changes that are required should be as small as possible without sacrificing the effectiveness of the new system. + This is especially true when the old system is in widespread use. + + + #. Corollary: **Migration to a new meta-build system should not be required without a very good reason.** + If a developer doesn't want the functionality offered by the new system, then she shouldn't be coerced into migrating from the old system unless there's something irrevocably broken about the old system (e.g., ``rosbuild``\ 's in-source build pattern and lack of an "install" step). + +#. + **Interoperability is a good thing.** + Whenever possible (not all combinations will be practical), developers should be able to mix and match meta-build systems, including mixing their different aspects (i.e., use the building tool from one system and the API from another). + Such mixing and matching is especially important when developers want to combine a large existing code base using one meta-build system (e.g., ROS with ``catkin``\ ) with new libraries and tools offered by a code base using another meta-build system (e.g., ROS2 with ``ament``\ ). + Ideally that kind of combination can be done without requiring changes to the API used by either code base and without telling the developer which builder tool to use. + + + #. Corollary: **Workspaces needn't be homogeneous.** + There's no reason that we shouldn't be able to freely mix, say, ``catkin`` and ``ament`` packages in one workspace, with dependencies going in both directions, so long as the builder tool in use knows how to build them both. + The primary interface between packages (at least, CMake-controlled packages) is their CMake configuration file. + So long as that configuration file follows the standard protocol (setting ``foo_LIBRARIES``\ , etc.), then it shouldn't matter who wrote the file. + It could be auto-generated by ``catkin`` or ``ament``\ , or even manually crafted by a developer who wants to use plain CMake in her package, but still have that package depended-upon by ``catkin`` or ``ament`` packages. + +Use cases, with experimental implementations +-------------------------------------------- + +Adding ROS packages to a ROS2 workspace and building with ``ament build`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's say that you want to add some existing ROS packages to your ROS2 workspace and don't want to migrate the ROS packages from ``catkin`` to ``ament`` (or vice versa). Here are two patches that let you do that: + + +* `ament_package `__\ : + Add support for format 1 package manifests, instead of requiring format 2. + This change isn't strictly related to ``catkin`` vs. ``ament``\ , because format 2 has been around for a while and ``catkin`` supports it, so developers could already update their manifests to format 2. + But there's a ton of ROS code out there that uses format 1, so we should support it. + This implementation could be improved, e.g., by reasoning over the various flavors of depend tags and how they differ between formats 1 and 2. +* `ament_tools `__\ : + Add a new ``catkin`` build type to ``ament``. + This implementation just treats ``catkin`` packages the same as plain ``cmake`` packages, which seems to work fine. + It could be made more sophisticated. + +Example usage: + + +#. Get the ROS2 code as usual, using the branches mentioned above. +#. Add to your workspace some ``catkin`` ROS packages, ensuring that all of their dependencies are satisfied (either also present in the workspace or installed elsewhere with appropriate setup shell files sourced). +#. Build as usual (e.g., ``./src/ament/ament_tools/scripts/ament.by build``\ ). + +Voila: your existing code isn't suddenly broken just because there's a new builder tool in use. + +Variation: Building ROS packages with ``ament build`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's say that you love the new ``ament`` tool and want to use it to build your existing ROS packages that use ``catkin`` internally. +Here's an example of how to do that, by doing a minimal installation of ``ament`` and then using it to build a workspace full of ROS ``catkin`` packages: + +.. code-block:: + + mkdir -p ~/ament_ws/src + cd ~/ament_ws/src + git clone https://github.com/osrf/osrf_pycommon.git + git clone https://github.com/ament/ament_package.git + cd ament_package + git checkout catkin + cd .. + git clone https://github.com/ament/ament_tools.git + cd ament_tools + git checkout catkin + cd ../.. + ./src/ament_tools/scripts/ament.py build + +Now build the ROS packages: + +.. code-block:: + + . $HOME/ament_ws/install/setup.bash + cd ~/ros_catkin_ws + ament build + +Voila: you used the ``ament`` build tool to build your ``catkin`` packages, without having to migrate them. + +Variation: Using the ``catkin`` API in a ROS2 package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's say that you're building on top of ROS2, which internally uses the ``ament`` API, and you want to add a new package using the ``catkin`` API. + +To make this work, we need a Python3 installation of ``catkin`` (the binary debians use Python2.7). +Here's an example of doing that, installing to ``$HOME/catkin``\ : + +.. code-block:: + + # install catkin_pkg + git clone https://github.com/ros-infrastructure/catkin_pkg.git + cd catkin_pkg + git checkout ament + python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb + # install catkin + git clone https://github.com/ros/catkin.git + cd catkin + git checkout ament + mkdir build + cd build + PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 + make install + +To use that version of catkin, you just need to source the ``$HOME/catkin/setup.bash`` file. + +Let's assume that you have the usual ROS2 workspace in ``~/ros2_ws``\ , and that you're on the ``catkin`` branches in ``ament_package`` and ``ament_tools``. +Add to that workspace the ``image_tools_catkin`` package from https://github.com/gerkey/catment. +It's a simple port of the ROS2 ``image_tools`` package, taking it from the ``ament`` API to the ``catkin`` API. +To build it: + +.. code-block:: + + cd ~/ros2_ws + . $HOME/catkin/setup.bash + ./src/ament/ament_tools/scripts/ament.py build + +Voila: when adding new packages atop ROS2, you're free to choose which CMake API you prefer inside your package. + + +* **Caveat**\ : I had to comment out the use of ``CATKIN_DEPENDS`` inside ``catkin_package()``\ , because somewhere somebody was getting upset that things like ``rclcpp`` aren't ``catkin`` packages. + That constraint needs to be relaxed somehow. +* **TODO**\ : The same demo but with a ``ament`` package that depends on a ``catkin`` package (this is easy). +* **TODO**\ : The same demo but with a package that has a vanilla ``CMakeLists.txt`` that uses neither ``ament`` nor ``catkin``\ , and provides a manually generated ``fooConfig.cmake`` file that exports the right stuff to make it look the same to outsiders. + +Building ROS2 packages with ``catkin_make_isolated`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's say that you're already familiar with ROS and ``catkin`` and that you're excited to try ROS2, but that you're not in the mood to learn about ``ament``. +You'd rather stick to what you know, such as using ``catkin_make_isolated`` to build everything. +Here is a patch that allows you to do that: + + +* `catkin `__\ : + Add support for packages that declare themselves to have a build type of ``ament_*``. + This implementation calls out to ``ament`` to build each such package. + While ``ament_cmake`` packages can be treated as plain ``cmake`` packages (as we did when adding ``catkin`` support to ``ament``\ ), ``ament_python`` packages require some gnarly invocations of Python. + Instead of trying to replicate that logic in ``catkin``\ , it's easier to just let ``ament`` handle it. + Also in this patch, we add the ``buildtool_export_depend`` packages to the set that are considered when building. +* `catkin_pkg `__\ : + Also in this patch, we add the ``buildtool_export_depend`` packages to the set that are considered when computing the topological order. + +Because we're going to call out to ``ament build``\ , we will also need a minimal installation of ``ament``\ , as did in a previous example: + +.. code-block:: + + mkdir -p ~/ament_ws/src + cd ~/ament_ws/src + git clone https://github.com/osrf/osrf_pycommon.git + git clone https://github.com/ament/ament_package.git + cd ament_package + git checkout catkin + cd .. + git clone https://github.com/ament/ament_tools.git + cd ament_tools + git checkout catkin + cd ../.. + ./src/ament_tools/scripts/ament.py build + +Then we need to install the modified version of catkin somewhere: + +.. code-block:: + + # install catkin_pkg + git clone https://github.com/ros-infrastructure/catkin_pkg.git + cd catkin_pkg + git checkout ament + python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb + # install catkin + git clone https://github.com/ros/catkin.git + cd catkin + git checkout ament + mkdir build + cd build + PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 + make install + +Now build the ROS2 packages: + +.. code-block:: + + . $HOME/catkin/setup.bash + . $HOME/ament_ws/install/setup.bash + cd ~/ros2_ws + touch src/eProsima/AMENT_IGNORE + PYTHONPATH=$PYTHONPATH:/home/gerkey/ros2_ws_catkin/install_isolated/lib/python3.5/site-packages catkin_make_isolated --install + +Voila: you've built ROS2 using the tools that you're familiar with. + + +* **Caveat**\ : we're ignoring the ``eProsima`` packages in the workspace because they lack ``package.xml`` files, which means that ``catkin`` can't see them. + ``ament`` has some heuristics for handling such packages. + Options: backport those heuristics to ``catkin``\ ; switch to installing non-\ ``package.xml``\ -containing packages outside of the workspace; or just add a ``package.xml`` to each of those packages (e.g., in our own fork). + +Combining all of ROS and ROS2 in one workspace and building it (TODO) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This step will require sorting out some things, including at least: + + +* Package name conflicts. + We currently have ROS2 versions of ROS message packages, as well as some stuff in ``geometry2``. + Either the functionality needs to be merged into one package that can support both systems, or the new versions need different names. +* Message generation. + ROS and ROS2 have different message generation steps, the output of which might or not might conflict. + Something sort of sophisticated needs to be done to allow generation of all the right artifacts from a single message package (or, as indicated above, the new message packages need different name). + +Using ``bloom`` to release ``ament`` packages (TODO) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It seems like ``bloom`` ought be able to release packages that use the ``ament`` CMake API, and that the resulting releases should be able to be built on the farm. +We can make changes to ``bloom`` and ``ros_buildfarm`` as needed to enable this use case. diff --git a/convert.sh b/convert.sh new file mode 100755 index 00000000000..fb216f7166e --- /dev/null +++ b/convert.sh @@ -0,0 +1,3 @@ +#find ./ -iname "*" -type f -exec sh -c 'echo "${0}"' {} \; +find ./ -iname "*" -type f -exec sh -c 'm2r "${0}"' {} \; + diff --git a/dummy-robot-demo.md b/dummy-robot-demo.md deleted file mode 100644 index 35f751a4d8c..00000000000 --- a/dummy-robot-demo.md +++ /dev/null @@ -1,69 +0,0 @@ -In this demo, we present a simple demo robot with all components from publishing joint states over publishing fake laser data until visualizing the robot model on a map in RViz. - -## Launching the demo -We assume your ROS2 installation dir as `~/ros2_ws`. Please change the directories according to your platform. - -To start the demo, we execute the demo bringup launch file, which we are going to explain in more details in the next section. - -``` -source ~/ros2_ws/install/setup.bash -ros2 launch dummy_robot_bringup dummy_robot_bringup.launch.py -# For ROS 2 releases prior to Bouncy, instead run: -# launch ~/ros2_ws/install/share/dummy_robot_bringup/launch/dummy_robot_bringup.py -``` - -You should see some prints inside your terminal along the lines of the following: -``` -[INFO] [launch]: process[dummy_map_server-1]: started with pid [25812] -[INFO] [launch]: process[robot_state_publisher-2]: started with pid [25813] -[INFO] [launch]: process[dummy_joint_states-3]: started with pid [25814] -[INFO] [launch]: process[dummy_laser-4]: started with pid [25815] -Initialize urdf model from file: /home/mikael/work/ros2/bouncy_ws/install_debug_isolated/dummy_robot_bringup/share/dummy_robot_bringup/launch/single_rrbot.urdf -Parsing robot urdf xml string. -Link single_rrbot_link1 had 1 children -Link single_rrbot_link2 had 1 children -Link single_rrbot_link3 had 2 children -Link single_rrbot_camera_link had 0 children -Link single_rrbot_hokuyo_link had 0 children -got segment single_rrbot_camera_link -got segment single_rrbot_hokuyo_link -got segment single_rrbot_link1 -got segment single_rrbot_link2 -got segment single_rrbot_link3 -got segment world -Adding fixed segment from world to single_rrbot_link1 -Adding moving segment from single_rrbot_link1 to single_rrbot_link2 -[INFO] [dummy_laser]: angle inc: 0.004363 -[INFO] [dummy_laser]: scan size: 1081 -[INFO] [dummy_laser]: scan time increment: 0.000028 -Adding moving segment from single_rrbot_link2 to single_rrbot_link3 -Adding fixed segment from single_rrbot_link3 to single_rrbot_camera_link -Adding fixed segment from single_rrbot_link3 to single_rrbot_hokuyo_link -``` - -If you now open in a next terminal your RViz, you'll see your robot. 🎉 - -``` -$ source /setup.bash -$ rviz2 -``` - -This opens RViz2. Assuming you have your dummy_robot_bringup still launched, you can now add the TF display plugin and configure your global frame to `world`. Once you did that, you should see a similar picture: - -![](https://i.imgur.com/pCFDTCv.png) - -### What's happening? -If you have a closer look at the launch file, we start a couple of nodes at the same time. - -* dummy_map_server -* dummy_laser -* dummy_joint_states -* robot_state_publisher - -The first two packages are relatively simple. The `dummy_map_server` constantly publishes an empty map with a periodic update. The `dummy_laser` does basically the same; publishing dummy fake laser scans. - -The `dummy_joint_states` node is publishing fake joint state data. As we are publishing a simple RRbot with only two joints, this node publishes joint states values for these two joints. - -The `robot_state_publisher` is doing the actual interesting work. It parses the given URDF file, extracts the robot model and listens to the incoming joint states. With this information, it publishes TF values for our robot which we visualize in RViz. - -Hooray! diff --git a/dummy-robot-demo.rst b/dummy-robot-demo.rst new file mode 100644 index 00000000000..9eb26a01f83 --- /dev/null +++ b/dummy-robot-demo.rst @@ -0,0 +1,80 @@ + +In this demo, we present a simple demo robot with all components from publishing joint states over publishing fake laser data until visualizing the robot model on a map in RViz. + +Launching the demo +------------------ + +We assume your ROS2 installation dir as ``~/ros2_ws``. Please change the directories according to your platform. + +To start the demo, we execute the demo bringup launch file, which we are going to explain in more details in the next section. + +.. code-block:: + + source ~/ros2_ws/install/setup.bash + ros2 launch dummy_robot_bringup dummy_robot_bringup.launch.py + # For ROS 2 releases prior to Bouncy, instead run: + # launch ~/ros2_ws/install/share/dummy_robot_bringup/launch/dummy_robot_bringup.py + +You should see some prints inside your terminal along the lines of the following: + +.. code-block:: + + [INFO] [launch]: process[dummy_map_server-1]: started with pid [25812] + [INFO] [launch]: process[robot_state_publisher-2]: started with pid [25813] + [INFO] [launch]: process[dummy_joint_states-3]: started with pid [25814] + [INFO] [launch]: process[dummy_laser-4]: started with pid [25815] + Initialize urdf model from file: /home/mikael/work/ros2/bouncy_ws/install_debug_isolated/dummy_robot_bringup/share/dummy_robot_bringup/launch/single_rrbot.urdf + Parsing robot urdf xml string. + Link single_rrbot_link1 had 1 children + Link single_rrbot_link2 had 1 children + Link single_rrbot_link3 had 2 children + Link single_rrbot_camera_link had 0 children + Link single_rrbot_hokuyo_link had 0 children + got segment single_rrbot_camera_link + got segment single_rrbot_hokuyo_link + got segment single_rrbot_link1 + got segment single_rrbot_link2 + got segment single_rrbot_link3 + got segment world + Adding fixed segment from world to single_rrbot_link1 + Adding moving segment from single_rrbot_link1 to single_rrbot_link2 + [INFO] [dummy_laser]: angle inc: 0.004363 + [INFO] [dummy_laser]: scan size: 1081 + [INFO] [dummy_laser]: scan time increment: 0.000028 + Adding moving segment from single_rrbot_link2 to single_rrbot_link3 + Adding fixed segment from single_rrbot_link3 to single_rrbot_camera_link + Adding fixed segment from single_rrbot_link3 to single_rrbot_hokuyo_link + +If you now open in a next terminal your RViz, you'll see your robot. 🎉 + +.. code-block:: + + $ source /setup.bash + $ rviz2 + +This opens RViz2. Assuming you have your dummy_robot_bringup still launched, you can now add the TF display plugin and configure your global frame to ``world``. Once you did that, you should see a similar picture: + + +.. image:: https://i.imgur.com/pCFDTCv.png + :target: https://i.imgur.com/pCFDTCv.png + :alt: + + +What's happening? +^^^^^^^^^^^^^^^^^ + +If you have a closer look at the launch file, we start a couple of nodes at the same time. + + +* dummy_map_server +* dummy_laser +* dummy_joint_states +* robot_state_publisher + +The first two packages are relatively simple. The ``dummy_map_server`` constantly publishes an empty map with a periodic update. The ``dummy_laser`` does basically the same; publishing dummy fake laser scans. + +The ``dummy_joint_states`` node is publishing fake joint state data. As we are publishing a simple RRbot with only two joints, this node publishes joint states values for these two joints. + +The ``robot_state_publisher`` is doing the actual interesting work. It parses the given URDF file, extracts the robot model and listens to the incoming joint states. With this information, it publishes TF values for our robot which we visualize in RViz. + +Hooray! diff --git a/tf2.md b/tf2.md deleted file mode 100644 index 48a3c1e0474..00000000000 --- a/tf2.md +++ /dev/null @@ -1,29 +0,0 @@ -# Using tf2 with ROS 2 - -There is preliminary support for [tf2](http://wiki.ros.org/tf2) in ROS 2. We rely heavily on tf2 in ROS 1 to manage data about coordinate transforms, and we expect to continue to use extensively in ROS 2. - -Here's how to try it out. In each shell, be sure to start by sourcing the ROS 2 setup file as usual (e.g. on Linux `. ~/ros2_ws/install/setup.bash` or on Windows `call C:\dev\ros2\install\setup.bat`). - -## Publishing transform data - -First run the [static_transform_publisher](http://wiki.ros.org/tf2_ros#static_transform_publisher) to generate `tf2` data: - - ros2 run tf2_ros static_transform_publisher 1 2 3 0.5 0.1 -1.0 foo bar - -That tool will publish a static transform from the parent frame `foo` to the child frame `bar` with (X, Y, Z) translation (1, 2, 3) and (roll, pitch, yaw) rotation (0.5, 0.1, -1.0). - -## Receiving transform data - -Now we can check whether it's possible to receive that transform data with `tf2_echo`: - - ros2 run tf2_ros tf2_echo foo bar - -You should see repeated output similar to this: - -~~~ -At time 0.0 -- Translation: [1.000, 2.000, 3.000] -- Rotation: in Quaternion [-0.475, -0.076, 0.240, 0.843] -~~~ - -Note that `tf2_echo` is reporting the rotation as a quaternion as opposed to roll, pitch, and yaw. diff --git a/tf2.rst b/tf2.rst new file mode 100644 index 00000000000..6f1164204f3 --- /dev/null +++ b/tf2.rst @@ -0,0 +1,39 @@ + +Using tf2 with ROS 2 +==================== + +There is preliminary support for `tf2 `__ in ROS 2. We rely heavily on tf2 in ROS 1 to manage data about coordinate transforms, and we expect to continue to use extensively in ROS 2. + +Here's how to try it out. In each shell, be sure to start by sourcing the ROS 2 setup file as usual (e.g. on Linux ``. ~/ros2_ws/install/setup.bash`` or on Windows ``call C:\dev\ros2\install\setup.bat``\ ). + +Publishing transform data +------------------------- + +First run the `static_transform_publisher `__ to generate ``tf2`` data: + +.. code-block:: + + ros2 run tf2_ros static_transform_publisher 1 2 3 0.5 0.1 -1.0 foo bar + + +That tool will publish a static transform from the parent frame ``foo`` to the child frame ``bar`` with (X, Y, Z) translation (1, 2, 3) and (roll, pitch, yaw) rotation (0.5, 0.1, -1.0). + +Receiving transform data +------------------------ + +Now we can check whether it's possible to receive that transform data with ``tf2_echo``\ : + +.. code-block:: + + ros2 run tf2_ros tf2_echo foo bar + + +You should see repeated output similar to this: + +.. code-block:: + + At time 0.0 + - Translation: [1.000, 2.000, 3.000] + - Rotation: in Quaternion [-0.475, -0.076, 0.240, 0.843] + +Note that ``tf2_echo`` is reporting the rotation as a quaternion as opposed to roll, pitch, and yaw.