├── simple-listener-dl-py
├── src
│ └── app
│ │ ├── resource
│ │ └── app
│ │ ├── app
│ │ ├── __init__.py
│ │ └── main.py
│ │ ├── ros2
│ │ ├── __init__.py
│ │ └── ros2_listener_ctrlx_provider.py
│ │ ├── setup.cfg
│ │ ├── ctrlx_datalayer
│ │ ├── __init__.py
│ │ ├── ctrlx_provider_node.py
│ │ └── ctrlx_datalayer_helper.py
│ │ ├── package.xml
│ │ └── setup.py
├── build-snap-amd64.sh
├── .vscode
│ └── settings.json
├── .gitignore
├── wrapper
│ └── run.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-talker-dl-py
├── src
│ └── app
│ │ ├── resource
│ │ └── app
│ │ ├── app
│ │ ├── __init__.py
│ │ └── main.py
│ │ ├── setup.cfg
│ │ ├── ros2
│ │ ├── __init__.py
│ │ └── datalayer_reader_ros2_publisher.py
│ │ ├── ctrlx_datalayer
│ │ ├── __init__.py
│ │ └── ctrlx_datalayer_helper.py
│ │ ├── package.xml
│ │ └── setup.py
├── build-snap-amd64.sh
├── .vscode
│ └── settings.json
├── .gitignore
├── wrapper
│ └── run.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-talker-py
├── src
│ └── talker
│ │ ├── resource
│ │ └── talker
│ │ ├── talker
│ │ ├── __init__.py
│ │ └── main_minimal_publisher.py
│ │ ├── setup.cfg
│ │ ├── package.xml
│ │ └── setup.py
├── build-snap-amd64.sh
├── .gitignore
├── wrapper
│ └── run.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-listener-py
├── src
│ └── listener
│ │ ├── resource
│ │ └── listener
│ │ ├── listener
│ │ ├── __init__.py
│ │ └── main_minimal_subscriber.py
│ │ ├── setup.cfg
│ │ ├── package.xml
│ │ └── setup.py
├── build-snap-amd64.sh
├── .gitignore
├── .vscode
│ ├── settings.json
│ └── launch.json
├── wrapper
│ └── run.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-listener-cpp
├── build-snap-amd64.sh
├── .vscode
│ └── settings.json
├── .gitignore
├── src
│ └── app
│ │ ├── package.xml
│ │ ├── CMakeLists.txt
│ │ └── src
│ │ └── subscriber_member_function.cpp
├── wrapper
│ └── run-listener.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-talker-cpp
├── build-snap-amd64.sh
├── .gitignore
├── src
│ └── app
│ │ ├── package.xml
│ │ ├── CMakeLists.txt
│ │ └── src
│ │ └── publisher_member_function.cpp
├── wrapper
│ └── run-talker.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-talker-dl-cpp
├── build-snap-amd64.sh
├── .gitignore
├── .vscode
│ ├── settings.json
│ └── tasks.json
├── src
│ └── app
│ │ ├── package.xml
│ │ ├── CMakeLists.txt
│ │ └── src
│ │ └── subscriber_member_function.cpp
├── wrapper
│ └── run-listener.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── simple-listener-dl-cpp
├── build-snap-amd64.sh
├── .gitignore
├── .vscode
│ ├── settings.json
│ └── tasks.json
├── src
│ └── app
│ │ ├── package.xml
│ │ ├── CMakeLists.txt
│ │ └── src
│ │ ├── ctrlx_datalayer_helper.h
│ │ └── subscriber_member_function.cpp
├── wrapper
│ └── run-listener.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── ros2-base-humble-deb
├── .gitignore
├── build-snap-amd64.sh
├── snap
│ └── snapcraft.yaml
└── README.md
├── LICENSES
├── LICENSE-images
├── MIT.txt
└── Apache-2.0.txt
├── SECURITY.md
├── scripts
├── prepare-build-snap.sh
├── colcon-build.sh
├── build-snap-py.sh
├── install-ctrlx-datalayer-deb.sh
├── build-snap-cpp.sh
├── setup-ctrlx-datalayer-deb.sh
├── README.md
├── install-snapcraft.sh
└── setup-system-humble-jammy.sh
├── CONTRIBUTORS.md
├── CONTRIBUTING.md
├── .editorconfig
├── LICENSE
├── .github
└── workflows
│ └── main.yml
├── CODE_OF_CONDUCT.md
├── README.md
└── .gitignore
/simple-listener-dl-py/src/app/resource/app:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/resource/app:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/resource/talker:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/resource/listener:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simple-talker-py/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-py.sh
--------------------------------------------------------------------------------
/simple-listener-cpp/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-cpp.sh
--------------------------------------------------------------------------------
/simple-listener-dl-py/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-py.sh
--------------------------------------------------------------------------------
/simple-listener-py/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-py.sh
--------------------------------------------------------------------------------
/simple-talker-cpp/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-cpp.sh
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-cpp.sh
--------------------------------------------------------------------------------
/simple-talker-dl-py/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-py.sh
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | ../scripts/build-snap-cpp.sh
--------------------------------------------------------------------------------
/simple-listener-cpp/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ros.distro": "humble"
3 | }
--------------------------------------------------------------------------------
/simple-listener-dl-py/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ros.distro": "humble"
3 | }
--------------------------------------------------------------------------------
/simple-talker-dl-py/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ros.distro": "humble"
3 | }
--------------------------------------------------------------------------------
/simple-talker-dl-py/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
--------------------------------------------------------------------------------
/simple-talker-py/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
--------------------------------------------------------------------------------
/ros2-base-humble-deb/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
--------------------------------------------------------------------------------
/simple-listener-dl-py/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
--------------------------------------------------------------------------------
/simple-listener-cpp/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
8 | squashfs-root/
--------------------------------------------------------------------------------
/simple-listener-py/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
8 | squashfs-root/
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
8 | squashfs-root/
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/app/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/setup.cfg:
--------------------------------------------------------------------------------
1 | [develop]
2 | script_dir=$base/lib/app
3 | [install]
4 | install_scripts=$base/lib/app
5 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
8 | squashfs-root/
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/app/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/ros2/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/setup.cfg:
--------------------------------------------------------------------------------
1 | [develop]
2 | script_dir=$base/lib/app
3 | [install]
4 | install_scripts=$base/lib/app
5 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/ros2/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/talker/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/listener/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/setup.cfg:
--------------------------------------------------------------------------------
1 | [develop]
2 | script_dir=$base/lib/talker
3 | [install]
4 | install_scripts=$base/lib/talker
5 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/ctrlx_datalayer/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/setup.cfg:
--------------------------------------------------------------------------------
1 | [develop]
2 | script_dir=$base/lib/listener
3 | [install]
4 | install_scripts=$base/lib/listener
5 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/ctrlx_datalayer/__init__.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
/ros2-base-humble-deb/build-snap-amd64.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | sudo snapcraft clean
5 | sudo snapcraft --build-for=amd64 --verbosity=verbose
--------------------------------------------------------------------------------
/simple-talker-cpp/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | __pycache__/
5 | prime/
6 | parts/
7 | stage/
8 | squashfs-root/
9 | .vscode/settings.json
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ros.distro": "humble",
3 | "files.associations": {
4 | "iostream": "cpp"
5 | }
6 | }
--------------------------------------------------------------------------------
/LICENSES/LICENSE-images:
--------------------------------------------------------------------------------
1 | This license applies only to the images, fonts and assets in this repository.
2 |
3 | All rights reserved.
4 |
5 | Copyright (c) Bosch Rexroth AG
6 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | You can find all information on how to report vulnerabilities at https://psirt.bosch.com/report-a-vulnerability/.
2 | Please include the repository URL in your report.
3 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ros.distro": "humble",
3 | "files.associations": {
4 | "functional": "cpp",
5 | "new": "cpp"
6 | }
7 | }
--------------------------------------------------------------------------------
/simple-listener-py/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[python]": {
3 | "editor.defaultFormatter": "ms-python.autopep8"
4 | },
5 | "python.formatting.provider": "none"
6 | }
--------------------------------------------------------------------------------
/scripts/prepare-build-snap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export GNUTLS_CPUID_OVERRIDE=0x1
4 | export DEBIAN_FRONTEND=noninteractive
5 | export SNAPCRAFT_BUILD_ENVIRONMENT=host
6 | export SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH=1
7 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | The following is a list of contributors to this repository in alphabetical order:
2 |
3 | * [Johannes Albrecht](https://github.com/albrecht-j), "Repo Maintainer"
4 | * [Sebastian Krauskopf](https://github.com/krauskopf)
5 |
--------------------------------------------------------------------------------
/scripts/colcon-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rosdep install -i --from-path src --rosdistro humble -y
4 | if [ $? -eq 0 ]
5 | then
6 | echo " "
7 | else
8 | exit 1
9 | fi
10 |
11 | source /opt/ros/humble/setup.bash
12 | colcon build
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | If you want to contribute please feel free to use the issues area or contact one of the team members marked within the CONTRIBUTORS.md. Contribution of source code is currently only possible for team members.
4 |
--------------------------------------------------------------------------------
/scripts/build-snap-py.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | ROOT_DIR=$(git rev-parse --show-toplevel)
5 |
6 | source ${ROOT_DIR}/scripts/colcon-build.sh
7 |
8 | if [ $? -eq 0 ]
9 | then
10 | echo " "
11 | else
12 | exit 1
13 | fi
14 |
15 | source ${ROOT_DIR}/scripts/prepare-build-snap.sh
16 |
17 | sudo snapcraft clean
18 | sudo snapcraft --build-for=amd64 --verbosity=verbose --destructive-mode
19 |
--------------------------------------------------------------------------------
/scripts/install-ctrlx-datalayer-deb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #set -e
4 | SDK_RELEASE_VERSION=${1:-3.4.0}
5 | DATALAYER_DEB_FILE_VERSION=${2:-2.8.6}
6 |
7 | ROOT_DIR=$(git rev-parse --show-toplevel)
8 |
9 | rm -rf ${ROOT_DIR}/deb
10 | mkdir -p ${ROOT_DIR}/deb
11 |
12 | wget --quiet https://github.com/boschrexroth/ctrlx-automation-sdk/releases/download/${SDK_RELEASE_VERSION}/ctrlx-datalayer-${DATALAYER_DEB_FILE_VERSION}.deb -P ${ROOT_DIR}/deb
13 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; https://editorconfig.org/
2 |
3 | root = true
4 |
5 | [*]
6 | insert_final_newline = true
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | indent_style = space
10 | indent_size = 2
11 |
12 | [{Makefile,go.mod,go.sum,*.go,.gitmodules}]
13 | indent_style = tab
14 | indent_size = 4
15 |
16 | [*.{md,txt}]
17 | indent_style = space
18 | indent_size = 4
19 | trim_trailing_whitespace = false
20 |
21 | eclint_indent_style = unset
--------------------------------------------------------------------------------
/scripts/build-snap-cpp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | ROOT_DIR=$(git rev-parse --show-toplevel)
5 |
6 | rm -rf install/
7 | mkdir -p install/app
8 | rm -rf build/
9 | rm -rf log/
10 |
11 | source ${ROOT_DIR}/scripts/colcon-build.sh
12 |
13 | if [ $? -eq 0 ]
14 | then
15 | echo " "
16 | else
17 | exit 1
18 | fi
19 |
20 | source ${ROOT_DIR}/scripts/prepare-build-snap.sh
21 |
22 | sudo snapcraft clean
23 | sudo snapcraft --build-for=amd64 --verbosity=verbose --destructive-mode
24 |
--------------------------------------------------------------------------------
/simple-listener-py/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Python: Current File",
9 | "type": "python",
10 | "request": "launch",
11 | "program": "${file}",
12 | "console": "integratedTerminal",
13 | "justMyCode": false
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/simple-talker-cpp/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.2.0
6 | Simple ROS 2 publisher (talker) in cpp
7 | boschrexroth
8 | MIT License
9 |
10 | ament_cmake
11 |
12 | rclcpp
13 | std_msgs
14 | sensor_msgs
15 |
16 | ament_lint_auto
17 | ament_lint_common
18 |
19 |
20 | ament_cmake
21 |
22 |
23 |
--------------------------------------------------------------------------------
/simple-listener-cpp/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.2.0
6 | Simple ROS 2 subscriber (listener) in cpp
7 | boschrexroth
8 | MIT License
9 |
10 | ament_cmake
11 |
12 | rclcpp
13 | std_msgs
14 | sensor_msgs
15 |
16 | ament_lint_auto
17 | ament_lint_common
18 |
19 |
20 | ament_cmake
21 |
22 |
23 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.2.0
6 | Simple ROS 2 subscriber (listener) in cpp
7 | boschrexroth
8 | MIT License
9 |
10 | ament_cmake
11 |
12 | rclcpp
13 | std_msgs
14 | sensor_msgs
15 |
16 | ament_lint_auto
17 | ament_lint_common
18 |
19 |
20 | ament_cmake
21 |
22 |
23 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.3.0
6 | Simple ROS 2 subscriber (listener) in cpp
7 | boschrexroth
8 | MIT License
9 |
10 | ament_cmake
11 |
12 | rclcpp
13 | std_msgs
14 | sensor_msgs
15 |
16 | ament_lint_auto
17 | ament_lint_common
18 |
19 |
20 | ament_cmake
21 |
22 |
23 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.2.0
6 | The package demonstrate a ROS2 listener
7 | boschrexroth
8 | MIT Licence
9 |
10 | ament_copyright
11 | ament_flake8
12 | ament_pep257
13 | python3-pytest
14 | rclpy
15 | std_msgs
16 |
17 |
18 | ament_python
19 |
20 |
21 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | app
5 | 2.2.0
6 | The package demonstrate a simple ROS2 talker (publisher)
7 | boschrexroth
8 | MIT Licence
9 |
10 | ament_copyright
11 | ament_flake8
12 | ament_pep257
13 | python3-pytest
14 | rclpy
15 | std_msgs
16 |
17 |
18 | ament_python
19 |
20 |
21 |
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | talker
5 | 0.0.0
6 | The package demonstrate a simple ROS2 talker (publisher)
7 | boschrexroth
8 | MIT Licence
9 |
10 | ament_copyright
11 | ament_flake8
12 | ament_pep257
13 | python3-pytest
14 | rclpy
15 | std_msgs
16 |
17 |
18 |
19 | ament_python
20 |
21 |
22 |
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | listener
5 | 0.0.0
6 | The package demonstrate a simple ROS2 subscriber (listener)
7 | boschrexroth
8 | MIT Licence
9 |
10 | ament_copyright
11 | ament_flake8
12 | ament_pep257
13 | python3-pytest
14 | rclpy
15 | std_msgs
16 |
17 |
18 |
19 | ament_python
20 |
21 |
22 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": [
3 | {
4 | "type": "cppbuild",
5 | "label": "C/C++: gcc build active file",
6 | "command": "/usr/bin/gcc",
7 | "args": [
8 | "-fdiagnostics-color=always",
9 | "-g",
10 | "${file}",
11 | "-o",
12 | "${fileDirname}/${fileBasenameNoExtension}"
13 | ],
14 | "options": {
15 | "cwd": "${fileDirname}"
16 | },
17 | "problemMatcher": [
18 | "$gcc"
19 | ],
20 | "group": {
21 | "kind": "build",
22 | "isDefault": true
23 | },
24 | "detail": "Task generated by Debugger."
25 | }
26 | ],
27 | "version": "2.0.0"
28 | }
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": [
3 | {
4 | "type": "cppbuild",
5 | "label": "C/C++: gcc build active file",
6 | "command": "/usr/bin/gcc",
7 | "args": [
8 | "-fdiagnostics-color=always",
9 | "-g",
10 | "${file}",
11 | "-o",
12 | "${fileDirname}/${fileBasenameNoExtension}"
13 | ],
14 | "options": {
15 | "cwd": "${fileDirname}"
16 | },
17 | "problemMatcher": [
18 | "$gcc"
19 | ],
20 | "group": {
21 | "kind": "build",
22 | "isDefault": true
23 | },
24 | "detail": "Task generated by Debugger."
25 | }
26 | ],
27 | "version": "2.0.0"
28 | }
--------------------------------------------------------------------------------
/simple-listener-dl-py/wrapper/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/app
17 |
--------------------------------------------------------------------------------
/simple-talker-cpp/wrapper/run-talker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/talker
--------------------------------------------------------------------------------
/simple-talker-dl-py/wrapper/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/app
17 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/setup.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | from setuptools import setup
6 |
7 | package_name = 'app'
8 |
9 | setup(
10 | name=package_name,
11 | version='2.2.0',
12 | packages=[package_name, 'ctrlx_datalayer', 'ros2'],
13 | data_files=[
14 | ('share/ament_index/resource_index/packages',
15 | ['resource/' + package_name]),
16 | ('share/' + package_name, ['package.xml'])
17 | ],
18 | install_requires=['setuptools'],
19 | zip_safe=True,
20 | maintainer='boschrexroth',
21 | maintainer_email='github@boschrexroth.com',
22 | description='Receives ROS2 message and writes the value into the ctrlX Data',
23 | license='MIT Licence',
24 | tests_require=['pytest'],
25 | entry_points={
26 | 'console_scripts': [
27 | 'app = app.main:main',
28 | ],
29 | },
30 | )
31 |
--------------------------------------------------------------------------------
/simple-listener-cpp/wrapper/run-listener.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/listener
--------------------------------------------------------------------------------
/simple-listener-py/wrapper/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/listener/lib/listener/subscriber
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/wrapper/run-listener.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/listener
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/setup.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | from setuptools import setup
6 |
7 | package_name = 'app'
8 |
9 | setup(
10 | name=package_name,
11 | version='2.2.0',
12 | packages=[package_name, 'ctrlx_datalayer', 'ros2'],
13 | data_files=[
14 | ('share/ament_index/resource_index/packages',
15 | ['resource/' + package_name]),
16 | ('share/' + package_name, ['package.xml'])
17 | ],
18 | install_requires=['setuptools'],
19 | zip_safe=True,
20 | maintainer='boschrexroth',
21 | maintainer_email='github@boschrexroth.com',
22 | description='Reads avalue from the ctrlX Data Layer and publishes it as ROS 2 message',
23 | license='MIT Licence',
24 | tests_require=['pytest'],
25 | entry_points={
26 | 'console_scripts': [
27 | 'app = app.main:main',
28 | ],
29 | },
30 | )
31 |
--------------------------------------------------------------------------------
/simple-talker-py/wrapper/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
15 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
16 | source $SNAP/local_setup.bash && $SNAP/talker/lib/talker/publisher
17 |
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/setup.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | from setuptools import setup
6 | import os
7 | from glob import glob
8 | package_name = 'talker'
9 |
10 | setup(
11 | name=package_name,
12 | version='0.0.0',
13 | packages=[package_name],
14 | data_files=[
15 | ('share/ament_index/resource_index/packages',
16 | ['resource/' + package_name]),
17 | ('share/' + package_name, ['package.xml'])
18 | ],
19 | install_requires=['setuptools'],
20 | zip_safe=True,
21 | maintainer='boschrexroth',
22 | maintainer_email="github@boschrexroth.com",
23 | description='The package demonstrate a simple ROS2 talker (publisher)',
24 | license='MIT Licence',
25 | tests_require=['pytest'],
26 | entry_points={
27 | 'console_scripts': [
28 | 'publisher = talker.main_minimal_publisher:main',
29 | ],
30 | },
31 | )
32 |
--------------------------------------------------------------------------------
/scripts/setup-ctrlx-datalayer-deb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit immediately if a command exits with a non-zero status.
4 | #set -e
5 |
6 | ROOT_DIR=$(git rev-parse --show-toplevel)
7 |
8 | echo "rootdir=$ROOT_DIR"
9 |
10 | rm -rf ${ROOT_DIR}/deb
11 |
12 | source ${ROOT_DIR}/scripts/install-ctrlx-datalayer-deb.sh ${1} ${2}
13 | cd ${ROOT_DIR}/deb
14 |
15 | sudo apt-get install -y dpkg-dev
16 |
17 | # Install debian package locally so that 'apt-get install' will find it (for building sample project snaps)
18 | dpkg-scanpackages -m . >Packages
19 |
20 | # Add package to sources list
21 | full_path=$(pwd)
22 | echo "deb [trusted=yes] file:${full_path} ./" | sudo tee /etc/apt/sources.list.d/ctrlx-automation.list
23 |
24 | # Fix the APT Error Download that is performed unsandboxed as root as
25 | echo "APT::Sandbox::User \"root\";" | sudo tee /etc/apt/apt.conf.d/10sandbox
26 |
27 | sudo apt-get update
28 |
29 | # Install newest ctrlx-datalayer package
30 | sudo apt-get install ctrlx-datalayer -y
31 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/app/main.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | # ROS Client Library for Python
6 | # https://docs.ros2.org/latest/api/rclpy/index.html
7 | import rclpy
8 |
9 | from ros2.ros2_listener_ctrlx_provider import Ros2ListenerDataLayerProvider
10 |
11 | def main(args=None):
12 | """
13 | The main function.
14 |
15 | Manages usage of the ROS Client Library
16 | """
17 | rclpy.init(args=args)
18 |
19 | ros2_publisher = Ros2ListenerDataLayerProvider(
20 | dl_address='ros2/listener/py/cpu-utilisation-percent',
21 | ros2_topic='ctrlXCpuUtilisationPercent')
22 |
23 | result = ros2_publisher.start()
24 | if result is False:
25 | ros2_publisher.stop()
26 | ros2_publisher.destroy_node()
27 | return
28 |
29 | rclpy.spin(ros2_publisher)
30 |
31 | ros2_publisher.stop()
32 | ros2_publisher.destroy_node()
33 | rclpy.shutdown()
34 |
35 |
36 | if __name__ == '__main__':
37 | main()
38 |
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/setup.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | from setuptools import setup
6 | import os
7 | from glob import glob
8 | package_name = 'listener'
9 |
10 | setup(
11 | name=package_name,
12 | version='0.0.0',
13 | packages=[package_name],
14 | data_files=[
15 | ('share/ament_index/resource_index/packages',
16 | ['resource/' + package_name]),
17 | ('share/' + package_name, ['package.xml']),
18 | (os.path.join('share', package_name), glob('*.json')),
19 | ],
20 | install_requires=['setuptools'],
21 | zip_safe=True,
22 | maintainer='boschrexroth',
23 | maintainer_email='github@boschrexroth.com',
24 | description='The package demonstrate a simple ROS2 subscriber (listener)',
25 | license='MIT Licence',
26 | tests_require=['pytest'],
27 | entry_points={
28 | 'console_scripts': [
29 | 'subscriber = listener.main_minimal_subscriber:main',
30 | ],
31 | },
32 | )
--------------------------------------------------------------------------------
/simple-talker-cpp/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-talker-cpp
2 | version: '2.4.0'
3 | summary: Snap with simple ROS 2 talker
4 | description: |
5 | A simple ROS 2 talker publishes messages on topic 'ros2_simple_cpp'.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 | architectures:
12 | - build-on: [amd64, arm64]
13 | build-for: [amd64]
14 | - build-on: [amd64, arm64]
15 | build-for: [arm64]
16 |
17 | parts:
18 | ros-app:
19 | plugin: dump
20 | source: install
21 |
22 | wrapper-scripts:
23 | plugin: dump
24 | source: wrapper/
25 | organize:
26 | ./run-talker.sh : usr/bin/run-talker
27 |
28 | apps:
29 | talker:
30 | command: usr/bin/run-talker
31 | plugs:
32 | - ros-base
33 | - network
34 | - network-bind
35 | daemon: simple
36 | passthrough:
37 | restart-condition: always
38 | restart-delay: 10s
39 |
40 | plugs:
41 | ros-base:
42 | interface: content
43 | content: executables
44 | target: $SNAP/rosruntime
45 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/wrapper/run-listener.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export ROS_BASE=$SNAP/rosruntime
3 | export PYTHONPATH=$PYTHONPATH:$ROS_BASE/lib/python3.10/site-packages
4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib
5 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/lib/$TRIPLET
6 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib
7 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/include/comm/datalayer/
8 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/x86_64-linux-gnu/
9 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROS_BASE/usr/lib/$TRIPLET
10 |
11 | export PATH=${PATH}:${ROS_BASE}/opt/ros/humble/bin
12 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ROS_BASE}/opt/ros/humble/lib
13 |
14 | #echo "run-listener PATH='${PATH}'"
15 | #echo "run-listener LD_LIBRARY_PATH='${LD_LIBRARY_PATH}'"
16 |
17 | source $ROS_BASE/opt/ros/humble/setup.bash #source if ros2 using debian package is build as a snap
18 | #source $ROS_BASE/setup.bash #source if ros2 is built from source
19 | source $SNAP/local_setup.bash && $SNAP/app/lib/app/listener
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/app/main.py:
--------------------------------------------------------------------------------
1 | """Reads a ctrlX Data Layer value and sends it via ROS 2 message."""
2 |
3 | # SPDX-FileCopyrightText: Bosch Rexroth AG
4 | #
5 | # SPDX-License-Identifier: MIT
6 |
7 | # ROS Client Library for Python
8 | # https://docs.ros2.org/latest/api/rclpy/index.html
9 | import rclpy
10 |
11 | from ros2.datalayer_reader_ros2_publisher import DataLayerReaderRos2Publisher
12 |
13 |
14 | def main(args=None):
15 | """Manage the usage of the ROS Client Library."""
16 | rclpy.init(args=args)
17 |
18 | ros2_publisher = DataLayerReaderRos2Publisher(
19 | dl_address='framework/metrics/system/cpu-utilisation-percent',
20 | ros2_topic='ctrlXCpuUtilisationPercent')
21 |
22 | result = ros2_publisher.start()
23 | if result is False:
24 | ros2_publisher.stop()
25 | ros2_publisher.destroy_node()
26 | return
27 |
28 | rclpy.spin(ros2_publisher)
29 |
30 | ros2_publisher.stop()
31 | ros2_publisher.destroy_node()
32 | rclpy.shutdown()
33 |
34 |
35 | if __name__ == '__main__':
36 | main()
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Bosch Rexroth AG
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | # Scrips Description
2 |
3 | ## Installation Scripts Files
4 |
5 | * __setup-ctrlx-datalayer-deb.sh__ installs the ctrlx-datalayer Debian package and registers its storage directory as local package source
6 | * __install-ctrlx-datalayer-deb.sh__ installs the ctrlx-datalayer Debian package, see [ctrlX AUTOMATION SDK/Releases](https://github.com/boschrexroth/ctrlx-automation-sdk/releases)
7 | * __setup-system-humble-jammy.sh__ installs the ROS2 Humble development environment [Install Ubuntu (deb packages)](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html)
8 |
9 | ``` bash
10 | # install default debian package
11 | ./install-ctrlx-datalayer-deb.sh
12 | ```
13 |
14 | ``` bash
15 | # install from SDK version 3.2.0 debian package version 2.7.5
16 | ./install-ctrlx-datalayer-deb.sh 3.2.0 2.7.5
17 | ```
18 |
19 | ## Build Scripts Files
20 |
21 | * __colcon-build.sh__ helper script for colon build, base on ROS2 __Humble__
22 | * __build-snap-cpp.sh__ helper script for creating snaps based on c++ projects
23 | * __build-snap-py.sh__ Help script for creating snaps based on python projects
24 |
25 | SPDX-License-Identifier: MIT
26 |
--------------------------------------------------------------------------------
/simple-talker-cpp/src/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(app)
3 |
4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
5 | add_compile_options(-Wall -Wextra -Wpedantic)
6 | endif()
7 |
8 | # find dependencies
9 | find_package(ament_cmake REQUIRED)
10 | find_package(rclcpp REQUIRED)
11 | find_package(std_msgs REQUIRED)
12 |
13 | if(BUILD_TESTING)
14 | find_package(ament_lint_auto REQUIRED)
15 | # the following line skips the linter which checks for copyrights
16 | # comment the line when a copyright and license is added to all source files
17 | set(ament_cmake_copyright_FOUND TRUE)
18 | # the following line skips cpplint (only works in a git repo)
19 | # comment the line when this package is in a git repo and when
20 | # a copyright and license is added to all source files
21 | set(ament_cmake_cpplint_FOUND TRUE)
22 | ament_lint_auto_find_test_dependencies()
23 | endif()
24 |
25 | add_executable(talker src/publisher_member_function.cpp)
26 | ament_target_dependencies(talker rclcpp std_msgs)
27 |
28 | install(TARGETS
29 | talker
30 | DESTINATION lib/${PROJECT_NAME})
31 |
32 | ament_package()
33 |
--------------------------------------------------------------------------------
/simple-listener-cpp/src/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(app)
3 |
4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
5 | add_compile_options(-Wall -Wextra -Wpedantic)
6 | endif()
7 |
8 | # find dependencies
9 | find_package(ament_cmake REQUIRED)
10 | find_package(rclcpp REQUIRED)
11 | find_package(std_msgs REQUIRED)
12 |
13 | if(BUILD_TESTING)
14 | find_package(ament_lint_auto REQUIRED)
15 | # the following line skips the linter which checks for copyrights
16 | # comment the line when a copyright and license is added to all source files
17 | set(ament_cmake_copyright_FOUND TRUE)
18 | # the following line skips cpplint (only works in a git repo)
19 | # comment the line when this package is in a git repo and when
20 | # a copyright and license is added to all source files
21 | set(ament_cmake_cpplint_FOUND TRUE)
22 | ament_lint_auto_find_test_dependencies()
23 | endif()
24 |
25 | add_executable(listener src/subscriber_member_function.cpp)
26 | ament_target_dependencies(listener rclcpp std_msgs)
27 |
28 | install(TARGETS
29 | listener
30 | DESTINATION lib/${PROJECT_NAME})
31 |
32 | ament_package()
33 |
--------------------------------------------------------------------------------
/simple-listener-cpp/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-listener-cpp
2 | version: '2.4.0'
3 | summary: Snap with simple ROS 2 listener
4 | description: |
5 | A simple ROS 2 listener which receives ROS 2 messages on topic 'ros2_simple_cpp'.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 |
12 | architectures:
13 | - build-on: [amd64, arm64]
14 | build-for: [amd64]
15 | - build-on: [amd64, arm64]
16 | build-for: [arm64]
17 |
18 | parts:
19 | ros-app:
20 | plugin: dump
21 | source: install
22 | override-build: |
23 | craftctl default
24 |
25 | wrapper-scripts:
26 | plugin: dump
27 | source: wrapper/
28 | organize:
29 | ./run-listener.sh : usr/bin/run-listener
30 |
31 | apps:
32 | listener:
33 | command: usr/bin/run-listener
34 | plugs:
35 | - ros-base
36 | - network
37 | - network-bind
38 | daemon: simple
39 | passthrough:
40 | restart-condition: always
41 | restart-delay: 10s
42 |
43 | plugs:
44 | ros-base:
45 | interface: content
46 | content: executables
47 | target: $SNAP/rosruntime
48 |
49 | lint:
50 | ignore:
51 | - library
52 |
--------------------------------------------------------------------------------
/simple-listener-py/src/listener/listener/main_minimal_subscriber.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | import rclpy
6 | from rclpy.node import Node
7 |
8 | from std_msgs.msg import String
9 |
10 |
11 | class MinimalSubscriber(Node):
12 |
13 | def __init__(self):
14 | super().__init__('minimal_subscriber')
15 | self.subscription = self.create_subscription(
16 | String,
17 | 'MinimalPublisher',
18 | self.listener_callback,
19 | 10)
20 | self.subscription # prevent unused variable warning
21 |
22 | def listener_callback(self, msg):
23 | self.get_logger().info('I heard: "%s"' % msg.data)
24 |
25 |
26 | def main(args=None):
27 | rclpy.init(args=args)
28 |
29 | minimal_subscriber = MinimalSubscriber()
30 |
31 | rclpy.spin(minimal_subscriber)
32 |
33 | # Destroy the node explicitly
34 | # (optional - otherwise it will be done automatically
35 | # when the garbage collector destroys the node object)
36 | minimal_subscriber.destroy_node()
37 |
38 | rclpy.shutdown()
39 |
40 |
41 | if __name__ == '__main__':
42 | main()
--------------------------------------------------------------------------------
/simple-listener-py/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-listener
2 | version: '2.4.0'
3 | summary: Simple ROS 2 listener
4 | description: |
5 | A simple ROS 2 listener to ROS 2 topic 'MinimalPublisher'.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 |
12 | architectures:
13 | - build-on: [amd64, arm64]
14 | build-for: [amd64]
15 | - build-on: [amd64, arm64]
16 | build-for: [arm64]
17 |
18 | parts:
19 | ros-app:
20 | plugin: dump
21 | source: install
22 | stage-packages: [libpython3.10]
23 | override-build: |
24 | craftctl default
25 |
26 | wrapper-scripts:
27 | plugin: dump
28 | source: wrapper/
29 | organize:
30 | ./run.sh : usr/bin/run
31 |
32 | apps:
33 | subscriber:
34 | command: usr/bin/run
35 | plugs:
36 | - ros-base
37 | - network
38 | - network-bind
39 | daemon: simple
40 | passthrough:
41 | restart-condition: always
42 | restart-delay: 10s
43 |
44 | plugs:
45 | ros-base:
46 | interface: content
47 | content: executables
48 | target: $SNAP/rosruntime
49 |
50 | lint:
51 | ignore:
52 | - library:
53 | - usr/lib/x86_64-linux-gnu/libpython3.10.so.*
--------------------------------------------------------------------------------
/LICENSES/MIT.txt:
--------------------------------------------------------------------------------
1 | This license applies only to the code in this repository.
2 | Images, fonts and other assets are explicitly excluded.
3 |
4 | MIT License
5 |
6 | Copyright (c) Bosch Rexroth AG
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-talker-dl-cpp
2 | version: '2.4.0'
3 | summary: Snap with simple ROS 2 listener
4 | description: |
5 | A simple ROS 2 listener which receives ROS 2 messages on topic 'ros2_simple_cpp'.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 | architectures:
12 | - build-on: [amd64, arm64]
13 | build-for: [amd64]
14 | - build-on: [amd64, arm64]
15 | build-for: [arm64]
16 |
17 | parts:
18 | ros-app:
19 | plugin: dump
20 | source: install
21 | stage-packages:
22 | - ctrlx-datalayer
23 | override-build: |
24 | craftctl default
25 |
26 | wrapper-scripts:
27 | plugin: dump
28 | source: wrapper/
29 | organize:
30 | ./run-listener.sh : usr/bin/run-listener
31 |
32 | apps:
33 | listener:
34 | command: usr/bin/run-listener
35 | plugs:
36 | - ros-base
37 | - network
38 | - network-bind
39 | daemon: simple
40 | passthrough:
41 | restart-condition: always
42 | restart-delay: 10s
43 |
44 | plugs:
45 | ros-base:
46 | interface: content
47 | content: executables
48 | target: $SNAP/rosruntime
49 |
50 | datalayer:
51 | interface: content
52 | content: datalayer
53 | target: $SNAP_DATA/.datalayer
54 |
--------------------------------------------------------------------------------
/simple-talker-py/src/talker/talker/main_minimal_publisher.py:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: Bosch Rexroth AG
2 | #
3 | # SPDX-License-Identifier: MIT
4 |
5 | import rclpy
6 | from rclpy.node import Node
7 |
8 | from std_msgs.msg import String
9 |
10 |
11 | class MinimalPublisher(Node):
12 |
13 | def __init__(self):
14 |
15 | super().__init__('MinimalPublisher')
16 |
17 | self.publisher_ = self.create_publisher(String, 'MinimalPublisher', 10)
18 | timer_period = 0.5 # seconds
19 | self.timer = self.create_timer(timer_period, self.timer_callback)
20 | self.i = 0
21 |
22 | def timer_callback(self):
23 |
24 | msg = String()
25 | msg.data = 'Hello World: %d' % self.i
26 | self.publisher_.publish(msg)
27 | self.get_logger().info('Publishing: "%s"' % msg.data)
28 | self.i += 1
29 |
30 |
31 |
32 | def main(args=None):
33 | rclpy.init(args=args)
34 |
35 | minimal_publisher = MinimalPublisher()
36 |
37 | rclpy.spin(minimal_publisher)
38 |
39 | # Destroy the node explicitly
40 | # (optional - otherwise it will be done automatically
41 | # when the garbage collector destroys the node object)
42 | minimal_publisher.destroy_node()
43 |
44 | rclpy.shutdown()
45 |
46 | if __name__ == '__main__':
47 | main()
48 |
--------------------------------------------------------------------------------
/simple-talker-py/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-talker-py
2 | version: '2.4.0'
3 | summary: Simple ROS 2 talker
4 | description: |
5 | A simple ROS 2 talker to ROS 2 topic 'MinimalPublisher'.
6 |
7 | base: core22
8 | grade: devel # must be 'stable' to release into candidate/stable channels
9 | confinement: strict
10 | type: app
11 |
12 | architectures:
13 | - build-on: [amd64, arm64]
14 | build-for: [amd64]
15 | - build-on: [amd64, arm64]
16 | build-for: [arm64]
17 |
18 | parts:
19 | # The `source` here is the tarred staging area of the ros-base snap.
20 | ros-app:
21 | plugin: dump
22 | source: install
23 | stage-packages: [libpython3.10]
24 | override-build: |
25 | craftctl default
26 |
27 | wrapper-scripts:
28 | plugin: dump
29 | source: wrapper/
30 | organize:
31 | ./run.sh : usr/bin/run
32 |
33 | apps:
34 | publisher:
35 | command: usr/bin/run
36 | plugs:
37 | - ros-base
38 | - network
39 | - network-bind
40 | daemon: simple
41 | passthrough:
42 | restart-condition: always
43 | restart-delay: 10s
44 |
45 | plugs:
46 | ros-base:
47 | interface: content
48 | content: executables
49 | target: $SNAP/rosruntime
50 |
51 | lint:
52 | ignore:
53 | - library:
54 | - usr/lib/x86_64-linux-gnu/libpython3.10.so.*
--------------------------------------------------------------------------------
/scripts/install-snapcraft.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | etc_environment=$(cat /etc/environment)
4 | if [[ ${etc_environment} != *"SNAPCRAFT_BUILD_ENVIRONMENT=host"* ]];then
5 | sudo echo "SNAPCRAFT_BUILD_ENVIRONMENT=host" | sudo tee -a /etc/environment
6 | fi
7 |
8 | if [[ ${etc_environment} != *"SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH=1"* ]];then
9 | sudo echo "SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH=1" | sudo tee -a /etc/environment
10 | fi
11 |
12 | function install_snapcraft() {
13 | echo ""
14 | echo "-------------------------------------------------------"
15 | echo "install snapcraft 7.x"
16 | echo "-------------------------------------------------------"
17 | echo ""
18 |
19 | sudo snap install snapcraft --channel=7.x/stable --classic
20 | }
21 |
22 | # Avoid return or exit, so that thsi sscript can be called from elsewhere
23 |
24 | snap_list=$(snap list)
25 | if [[ ${snap_list} != *"snapcraft"* ]];then
26 | # snapcraft is not installed, so install it
27 | install_snapcraft
28 | else
29 | # snapcraft is installed
30 | snapcraft_installed=$(snap list snapcraft)
31 | if [[ ${snapcraft_installed} != *"7."* ]];then
32 | # but not the desired version, so remove this versin and install the right one
33 | echo Uninstalling inappropriate snapcraft version...
34 | sudo snap remove snapcraft 2>/dev/null
35 | install_snapcraft
36 | fi
37 | fi
38 |
39 |
--------------------------------------------------------------------------------
/ros2-base-humble-deb/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-base-humble
2 | version: '2.4.0'
3 | summary: ROS 2 Humble base snap for ctrlX CORE
4 | description: |
5 | Provides ROS 2 Humble for ROS 2 applications running on a for ctrlX CORE.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 |
12 | architectures:
13 | - build-on: [amd64, arm64]
14 | build-for: [amd64]
15 | - build-on: [amd64, arm64]
16 | build-for: [arm64]
17 |
18 | parts:
19 | ros-base:
20 | plugin: colcon
21 | build-packages: [make, gcc, g++]
22 | stage-packages: [
23 | software-properties-common,
24 | ros-humble-ros-base,
25 | python3-argcomplete,
26 | ca-certificates
27 | ]
28 | build-environment:
29 | - ROS_VERSION: '2'
30 | - ROS_DISTRO: humble
31 | source: ./
32 |
33 | datalayer:
34 | plugin: nil
35 | stage-packages:
36 | - ctrlx-datalayer
37 |
38 | helper:
39 | plugin: python
40 | build-environment:
41 | - PYTHONPATH: "$CRAFT_PART_INSTALL/usr/lib/python3/dist-packages"
42 | stage-packages:
43 | - python3-wheel
44 | - python3.10-venv
45 | python-packages:
46 | - ctrlx-datalayer
47 | - empy
48 | - numpy
49 | - rosdep
50 | - rosdistro
51 | - colcon-core
52 | - lark
53 | source: ./
54 |
55 | slots:
56 | ros-base:
57 | interface: content
58 | content: executables
59 | read: [/]
60 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-simple-listener-dl-cpp
2 | version: '2.4.0'
3 | summary: Snap with simple ROS 2 listener
4 | description: |
5 | A simple ROS 2 listener which receives ROS 2 messages on topic 'ros2_simple_cpp'.
6 |
7 | base: core22
8 | grade: stable
9 | confinement: strict
10 | type: app
11 |
12 | architectures:
13 | - build-on: [amd64, arm64]
14 | build-for: [amd64]
15 | - build-on: [amd64, arm64]
16 | build-for: [arm64]
17 |
18 | parts:
19 | ros-app:
20 | plugin: dump
21 | source: install
22 | stage-packages:
23 | - ctrlx-datalayer
24 | override-build: |
25 | craftctl default
26 |
27 | wrapper-scripts:
28 | plugin: dump
29 | source: wrapper/
30 | organize:
31 | ./run-listener.sh : usr/bin/run-listener
32 |
33 | apps:
34 | listener:
35 | command: usr/bin/run-listener
36 | plugs:
37 | - ros-base
38 | - network
39 | - network-bind
40 | daemon: simple
41 | passthrough:
42 | restart-condition: always
43 | restart-delay: 10s
44 |
45 | plugs:
46 | ros-base:
47 | interface: content
48 | content: executables
49 | target: $SNAP/rosruntime
50 |
51 | datalayer:
52 | interface: content
53 | content: datalayer
54 | target: $SNAP_DATA/.datalayer
55 |
56 | lint:
57 | ignore:
58 | - library:
59 | - usr/lib/aarch64-linux-gnu/libcomm_datalayer.so.*
60 | - usr/lib/x86_64-linux-gnu/libcomm_datalayer.so.*
61 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-talker-dl-py
2 | version: '2.4.0'
3 | summary: Publishes ctrlX Data Layer value to ROS 2
4 | description: |
5 | A ROS 2 talker:
6 | Reads ctrlX Data Layer value framework/metrics/system/cpu-utilisation-percent
7 | and publishes it to ROS 2 topic 'ctrlXCpuUtilisationPercent'.
8 |
9 | base: core22
10 | grade: devel # must be 'stable' to release into candidate/stable channels
11 | confinement: strict
12 | type: app
13 |
14 | architectures:
15 | - build-on: [amd64, arm64]
16 | build-for: [amd64]
17 | - build-on: [amd64, arm64]
18 | build-for: [arm64]
19 |
20 | parts:
21 | # The `source` here is the tarred staging area of the ros-base snap.
22 | ros-app:
23 | plugin: dump
24 | source: install
25 | stage-packages: [libpython3.10]
26 | override-build: |
27 | craftctl default
28 |
29 | wrapper-scripts:
30 | plugin: dump
31 | source: wrapper/
32 | organize:
33 | ./run.sh : usr/bin/run
34 |
35 | apps:
36 | publisher:
37 | command: usr/bin/run
38 | plugs:
39 | - ros-base
40 | - network
41 | - network-bind
42 | daemon: simple
43 | passthrough:
44 | restart-condition: always
45 | restart-delay: 10s
46 |
47 | plugs:
48 | ros-base:
49 | interface: content
50 | content: executables
51 | target: $SNAP/rosruntime
52 | datalayer:
53 | interface: content
54 | content: datalayer
55 | target: $SNAP_DATA/.datalayer
56 |
57 | lint:
58 | ignore:
59 | - library:
60 | - usr/lib/x86_64-linux-gnu/libpython3.10.so.*
--------------------------------------------------------------------------------
/simple-listener-dl-py/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: ros2-listener-dl-py
2 | version: '2.4.0'
3 | summary: ROS 2 listener stores a received ROS 2 message into a ctrlX Data Layer node
4 | description: |
5 | A ROS 2 listener:
6 | Receives a ROS 2 message and writes it into the ctrlX Data Layer node
7 | ros2/listener-dl/cpu-utilisation-percent.
8 |
9 | base: core22
10 | grade: devel # must be 'stable' to release into candidate/stable channels
11 | confinement: strict
12 | type: app
13 |
14 | architectures:
15 | - build-on: [amd64, arm64]
16 | build-for: [amd64]
17 | - build-on: [amd64, arm64]
18 | build-for: [arm64]
19 |
20 | parts:
21 | # The `source` here is the tarred staging area of the ros-base snap.
22 | ros-app:
23 | plugin: dump
24 | source: install
25 | stage-packages: [libpython3.10]
26 | override-build: |
27 | craftctl default
28 |
29 | wrapper-scripts:
30 | plugin: dump
31 | source: wrapper/
32 | organize:
33 | ./run.sh : usr/bin/run
34 |
35 | apps:
36 | publisher:
37 | command: usr/bin/run
38 | plugs:
39 | - ros-base
40 | - network
41 | - network-bind
42 | daemon: simple
43 | passthrough:
44 | restart-condition: always
45 | restart-delay: 10s
46 |
47 | plugs:
48 | ros-base:
49 | interface: content
50 | content: executables
51 | target: $SNAP/rosruntime
52 | datalayer:
53 | interface: content
54 | content: datalayer
55 | target: $SNAP_DATA/.datalayer
56 |
57 | lint:
58 | ignore:
59 | - library:
60 | - usr/lib/x86_64-linux-gnu/libpython3.10.so.*
61 |
--------------------------------------------------------------------------------
/simple-listener-cpp/src/app/src/subscriber_member_function.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Open Source Robotics Foundation, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 |
18 | #include "rclcpp/rclcpp.hpp"
19 | #include "std_msgs/msg/string.hpp"
20 |
21 | using std::placeholders::_1;
22 |
23 | class MinimalSubscriber : public rclcpp::Node
24 | {
25 | public:
26 | MinimalSubscriber()
27 | : Node("minimal_subscriber")
28 | {
29 | m_subscription = this->create_subscription(
30 | "ros2_simple_talker_cpp", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
31 | }
32 |
33 | private:
34 | void topic_callback(const std_msgs::msg::String & msg) const
35 | {
36 | RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str());
37 | }
38 | rclcpp::Subscription::SharedPtr m_subscription;
39 | };
40 |
41 | int main(int argc, char * argv[])
42 | {
43 | rclcpp::init(argc, argv);
44 | rclcpp::spin(std::make_shared());
45 | rclcpp::shutdown();
46 | return 0;
47 | }
48 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | # With this workflow, snaps are created from each example.
2 |
3 | name: Build Snap
4 |
5 | # Controls when the action will run.
6 | on:
7 | # Triggers the workflow on push or pull request events but only for the main branch
8 | push:
9 | branches: [ main ]
10 | pull_request:
11 | branches: [ main ]
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | jobs:
17 | SetupAndBuild:
18 | #runs-on: ubuntu-latest
19 | runs-on: ubuntu-22.04
20 | strategy:
21 | fail-fast: false
22 | steps:
23 | - name: Setup ROS
24 | uses: ros-tooling/setup-ros@v0.7
25 | env:
26 | SNAPCRAFT_BUILD_ENVIRONMENT: host
27 | SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH: 1
28 | - run: vcs --help
29 |
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 | with:
33 | fetch-depth: 0
34 |
35 | - name: Install snapcraft
36 | run: sudo snap install snapcraft --channel=7.x/stable --classic
37 |
38 | - name: Update ROS development
39 | run: rosdep update
40 |
41 | - name: Set up Snapcraft env
42 | run: |
43 | echo "SNAPCRAFT_BUILD_ENVIRONMENT=host" >> "$GITHUB_ENV"
44 | echo "SNAPCRAFT_ENABLE_EXPERIMENTAL_TARGET_ARCH=1" >> "$GITHUB_ENV"
45 |
46 | - run: |
47 | cd simple-listener-py
48 | ./build-snap-amd64.sh
49 | - run: |
50 | cd simple-listener-cpp
51 | ./build-snap-amd64.sh
52 | - run: |
53 | cd simple-listener-dl-py
54 | ./build-snap-amd64.sh
55 | - run: |
56 | cd simple-talker-py
57 | ./build-snap-amd64.sh
58 | - run: |
59 | cd simple-talker-cpp
60 | ./build-snap-amd64.sh
61 | - run: |
62 | cd simple-talker-dl-py
63 | ./build-snap-amd64.sh
64 |
--------------------------------------------------------------------------------
/scripts/setup-system-humble-jammy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # see: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html
6 | echo "Setup ROS2 Humble environment"
7 |
8 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 | # +++++++++ Set locale +++++++++
10 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 | echo "-- Set locale"
12 | locale # check for UTF-8
13 |
14 | sudo apt update && sudo apt install locales
15 | sudo locale-gen en_US en_US.UTF-8
16 | sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
17 | export LANG=en_US.UTF-8
18 |
19 | locale # verify settings
20 |
21 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 | # +++++++++ Setup Sources +++++++++
23 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 | echo "-- Add the ROS 2 apt repository"
25 |
26 | sudo apt install software-properties-common
27 | sudo add-apt-repository universe -y
28 |
29 | ## Now add the ROS 2 GPG key with apt.
30 | sudo apt update && sudo apt install curl -y
31 | sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
32 |
33 | ## Then add the repository to your sources list.
34 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
35 |
36 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 | # +++++++++ Install ROS 2 packages +++++++++
38 | # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39 | echo "-- Install ROS 2 packages"
40 | sudo apt update && sudo apt upgrade -y
41 |
42 | ## ROS-Base Install (Bare Bones): Communication libraries, message packages, command line tools. No GUI tools.
43 | sudo apt install -y ros-humble-ros-base
44 |
45 | ## Development tools: Compilers and other tools to build ROS packages
46 | sudo apt install -y ros-dev-tools
47 |
48 |
--------------------------------------------------------------------------------
/simple-talker-cpp/src/app/src/publisher_member_function.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Open Source Robotics Foundation, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "rclcpp/rclcpp.hpp"
21 | #include "std_msgs/msg/string.hpp"
22 |
23 | using namespace std::chrono_literals;
24 |
25 | /* This example creates a subclass of Node and uses std::bind() to register a
26 | * member function as a callback from the timer. */
27 |
28 | class MinimalPublisher : public rclcpp::Node
29 | {
30 | rclcpp::TimerBase::SharedPtr m_timer;
31 | rclcpp::Publisher::SharedPtr m_publisher;
32 | size_t m_count;
33 |
34 | public:
35 | MinimalPublisher()
36 | : Node("minimal_publisher"), m_count(0)
37 | {
38 | m_publisher = this->create_publisher("ros2_simple_talker_cpp", 10);
39 | m_timer = this->create_wall_timer(
40 | 500ms, std::bind(&MinimalPublisher::timer_callback, this));
41 | }
42 |
43 | private:
44 | void timer_callback()
45 | {
46 | auto message = std_msgs::msg::String();
47 | message.data = "Hello, world! " + std::to_string(m_count++);
48 | RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
49 | m_publisher->publish(message);
50 | }
51 | };
52 |
53 | int main(int argc, char * argv[])
54 | {
55 | rclcpp::init(argc, argv);
56 | rclcpp::spin(std::make_shared());
57 | rclcpp::shutdown();
58 | return 0;
59 | }
60 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/src/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(app)
3 | set(TARGET_PROJECT_NAME listener)
4 |
5 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
6 | add_compile_options(-Wall -Wextra -Wpedantic)
7 | endif()
8 |
9 | # find dependencies
10 | find_package(ament_cmake REQUIRED)
11 | find_package(rclcpp REQUIRED)
12 | find_package(std_msgs REQUIRED)
13 |
14 |
15 | #
16 | # Set link directories
17 | #
18 | MESSAGE( STATUS "Libraries directory: ${LIBRARY_DIR}")
19 | link_directories(
20 | ${LIBRARY_DIR}
21 | ${LIBRARY_DEP_DIR}
22 | )
23 |
24 | # User dependency directory
25 | #
26 | set (USER_DEPENDENCY_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
27 |
28 | SET ( PRIVATE_INCLUDE_DIRS
29 | ${CMAKE_CURRENT_LIST_DIR}
30 | ${CMAKE_CURRENT_BINARY_DIR}
31 | ${CMAKE_CURRENT_LIST_DIR}/include
32 | ${USER_DEPENDENCY_DIR}/include
33 | ${USER_DEPENDENCY_DIR}/include/comm.datalayer
34 | )
35 |
36 | # Set target link libraries
37 |
38 |
39 | if(BUILD_TESTING)
40 | find_package(ament_lint_auto REQUIRED)
41 | # the following line skips the linter which checks for copyrights
42 | # comment the line when a copyright and license is added to all source files
43 | set(ament_cmake_copyright_FOUND TRUE)
44 | # the following line skips cpplint (only works in a git repo)
45 | # comment the line when this package is in a git repo and when
46 | # a copyright and license is added to all source files
47 | set(ament_cmake_cpplint_FOUND TRUE)
48 | ament_lint_auto_find_test_dependencies()
49 | endif()
50 |
51 | add_executable(listener src/subscriber_member_function.cpp)
52 | ament_target_dependencies(listener rclcpp std_msgs)
53 |
54 |
55 | #
56 | # Set target include directories
57 | #
58 | target_include_directories ( ${TARGET_PROJECT_NAME}
59 | PUBLIC ${PUBLIC_INCLUDE_DIRS}
60 | PUBLIC ${LIBRARY_INCLUDES}
61 | PRIVATE ${PRIVATE_INCLUDE_DIRS}
62 | )
63 | #
64 | target_link_libraries(${TARGET_PROJECT_NAME} -Wl,--no-undefined)
65 | target_link_libraries(${TARGET_PROJECT_NAME}
66 | libcomm_datalayer.so
67 | pthread
68 | ssl
69 | crypto
70 | )
71 |
72 | install(TARGETS
73 | listener
74 | DESTINATION lib/${PROJECT_NAME})
75 |
76 | ament_package()
77 |
--------------------------------------------------------------------------------
/simple-talker-cpp/README.md:
--------------------------------------------------------------------------------
1 | # Simple ROS 2 Publisher in C++
2 |
3 | ROS 2 node which publishes messages under the topic `ros2_simple_cpp`.
4 |
5 | ## Prerequisites
6 |
7 | * `ros-base` snap. The base snap which provides the ROS 2 runtime binaries. Has to be installed on ctrlX OS. See [ROS 2 Humble Base Snap](../ros2-base-humble-deb/README.md).
8 | * An Ubuntu based build environment to build an app. See [ctrlX Automation SDK](https://github.com/boschrexroth/ctrlx-automation-sdk).
9 |
10 | ## Basis for this Project
11 |
12 | This project is based on the official ROS 2 Tutorial: [Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-c).
13 |
14 | ## Building a snap
15 |
16 | Building a snap has two steps:
17 |
18 | 1. Colcon build: CMakeLists.txt defines how compile and link the C++ sources.
19 | 2. snap build: snap/snapcraft.yaml defines how the compiled binaries are packed into the snap and how they are called on the ctrlX CORE.
20 |
21 | ### Colcon Configuration
22 |
23 | The colcon build tool is configured by `CMakeLists.txt`.
24 |
25 | This section defines the ROS 2 packages needed:
26 |
27 | find_package(ament_cmake REQUIRED)
28 | find_package(rclcpp REQUIRED)
29 | find_package(std_msgs REQUIRED)
30 |
31 | And here the executables and their dependencies are defined:
32 |
33 | add_executable(listener src/subscriber_member_function.cpp)
34 | ament_target_dependencies(listener rclcpp std_msgs)
35 |
36 | ### Snapcraft Configuration
37 |
38 | `snap/snapcraft.yaml` defines how the snap will be build:
39 |
40 | * `install/` is dumped into the snap
41 | * also `wrapper/`
42 | * Two apps (talker and listener) are copied into the snap and started as services
43 | * The snap - respectively the executables - uses the content interface of the `ros-base` snap (here the ROS 2 runtime is provided).
44 |
45 | ### Build the snap
46 |
47 | Start this script:
48 |
49 | ./build-snap-amd64.sh
50 |
51 | ## About
52 |
53 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
54 |
55 |
56 |
57 | ## Licenses
58 |
59 | SPDX-License-Identifier: Apache-2.0
60 |
--------------------------------------------------------------------------------
/simple-listener-cpp/README.md:
--------------------------------------------------------------------------------
1 | # Simple ROS 2 Subscriber in C++
2 |
3 | A simple ROS 2 node which subscribes to messages of the topic `ros2_simple_cpp`.
4 |
5 | ## Prerequisites
6 |
7 | * `ros-base` snap. The base snap which provides the ROS 2 runtime binaries. Has to be installed on ctrlX OS. See [ROS 2 Humble Base Snap](../ros2-base-humble-deb/README.md).
8 | * An Ubuntu based build environment to build an app. See [ctrlX Automation SDK](https://github.com/boschrexroth/ctrlx-automation-sdk).
9 |
10 | ## Basis for this Project
11 |
12 | This project is based on the official ROS 2 Tutorial: [Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-c).
13 |
14 | ## Building a Snap
15 |
16 | Building a snap has two steps:
17 |
18 | 1. Colcon build: `CMakeLists.txt` defines how compile and link the C++ sources.
19 | 2. snap build: `snap/snapcraft.yaml` defines how the compiled binaries are packed into the snap and how they are called on ctrlX OS.
20 |
21 | ### Colcon Configuration
22 |
23 | The colcon build tool is configured by `CMakeLists.txt`.
24 |
25 | This section defines the ROS 2 packages needed:
26 |
27 | find_package(ament_cmake REQUIRED)
28 | find_package(rclcpp REQUIRED)
29 | find_package(std_msgs REQUIRED)
30 |
31 | And here the executables and their dependencies are defined:
32 |
33 | add_executable(listener src/subscriber_member_function.cpp)
34 | ament_target_dependencies(listener rclcpp std_msgs)
35 |
36 | ### Snapcraft Configuration
37 |
38 | `snap/snapcraft.yaml` defines how the snap will be build:
39 |
40 | * `install/` is dumped into the snap
41 | * also `wrapper/`
42 | * Two apps (talker and listener) are copied into the snap and started as services
43 | * The snap - respectively the executables - uses the content interface of the `ros-base` snap (here the ROS 2 runtime is provided).
44 |
45 | ### Build the Snap
46 |
47 | Start this script:
48 |
49 | ./build-snap-amd64.sh
50 |
51 | ## About
52 |
53 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
54 |
55 |
56 |
57 | ## Licenses
58 |
59 | SPDX-License-Identifier: Apache-2.0
--------------------------------------------------------------------------------
/simple-listener-dl-py/README.md:
--------------------------------------------------------------------------------
1 | # ROS 2 Listener that Writes a ctrlX Data Layer Value (Python)
2 |
3 | ## Introduction
4 |
5 | This project implements a ROS 2 listener, which receives a ROS 2 message and writes the value into a ctrlX Data Layer node.
6 |
7 | [Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-python) was used as template.
8 |
9 | See also:
10 |
11 | * [Canonical Snapcraft - Deploying robotics applications](https://snapcraft.io/docs/robotics)
12 | * [Canonical - How to build a snap using ROS 2 Humble](https://canonical.com/blog/how-to-build-a-snap-using-ros-2-humble)
13 |
14 | ## Implementation
15 |
16 | * The directory structure is according colcon packages.
17 | * In `setup.py` and `setup.cfg` the [colcon](https://colcon.readthedocs.io/en/released/) package is defined.
18 | * `src/talker/talker/main.py` provides the main function
19 | * `src/talker/ros2/datalayer_reader_ros2_publisher.py` reads a ctrlX Data Layer values, creates a ROS 2 message and publishes it under the topic `ctrlXCpuUtilisationPercent`.
20 | * `src/talker/ctrlx_datalayer/ctrlx_datalayer_helper.py` contains helper functions regarding ctrlX Data Layer
21 | * `snap/snapcraft.yaml` defines which files are packed into the snap.
22 |
23 | ## Build process
24 |
25 | To build a snap run
26 |
27 | ./build-snap-amd64.sh
28 |
29 | The script contains following build steps:
30 |
31 | 1. Build the colcon package:
32 |
33 | colcon build
34 |
35 | 2. Clean the snapcraft helper directories:
36 |
37 | snapcraft clean --destructive-mode
38 |
39 | 3. Update helper directories and build the snap:
40 |
41 | snapcraft --destructive-mode
42 |
43 | Hint: Arm64-cross-build is not supported.
44 |
45 | ## Installation and test
46 |
47 | The `ros2-base` snap must already be installed.
48 |
49 | Install the created snap on a ctrlX OS.
50 |
51 | It publishes at the ROS 2 topic `MinimalPublisher`.
52 |
53 | The output can be checked with:
54 |
55 | sudo snap logs -f ros2-simple-talker
56 |
57 | ## About
58 |
59 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
60 |
61 |
62 |
63 | ## Licenses
64 |
65 | SPDX-License-Identifier: Apache-2.0
66 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/README.md:
--------------------------------------------------------------------------------
1 | # Simple ROS 2 Subscriber in C++
2 |
3 | A simple ROS 2 node which subscribes to ROS messages of the topic `ros2_simple_talker_cpp` and publishes the value to the ctrlX Data Layer at the address `ros/listenercpp/mymessage`. From there the value can be used in any ctrlX App.
4 |
5 | ## Prerequisites
6 |
7 | * `ros-base` snap. The base snap which provides the ROS 2 runtime binaries. Has to be installed on ctrlX OS. See [ROS 2 Humble Base Snap](../ros2-base-humble-deb/README.md).
8 | * An Ubuntu based build environment to build an app. See [ctrlX Automation SDK](https://github.com/boschrexroth/ctrlx-automation-sdk).
9 |
10 | ## Basis for this Project
11 |
12 | This project is based on the official ROS 2 Tutorial: [Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-c).
13 |
14 | ## Building a Snap
15 |
16 | Building a snap has two steps:
17 |
18 | 1. Colcon build: `CMakeLists.txt` defines how compile and link the C++ sources.
19 | 2. snap build: `snap/snapcraft.yaml` defines how the compiled binaries are packed into the snap and how they are called on ctrlX OS.
20 |
21 | ### Colcon Configuration
22 |
23 | The colcon build tool is configured by `CMakeLists.txt`.
24 |
25 | This section defines the ROS 2 packages needed:
26 |
27 | find_package(ament_cmake REQUIRED)
28 | find_package(rclcpp REQUIRED)
29 | find_package(std_msgs REQUIRED)
30 |
31 | And here the executables and their dependencies are defined:
32 |
33 | add_executable(listener src/subscriber_member_function.cpp)
34 | ament_target_dependencies(listener rclcpp std_msgs)
35 |
36 | ### Snapcraft Configuration
37 |
38 | `snap/snapcraft.yaml` defines how the snap will be build:
39 |
40 | * `install/` is dumped into the snap
41 | * also `wrapper/`
42 | * Two apps (talker and listener) are copied into the snap and started as services
43 | * The snap - respectively the executables - uses the content interface of the `ros-base` snap (here the ROS 2 runtime is provided).
44 |
45 | ### Build the Snap
46 |
47 | Start this script:
48 |
49 | ./build-snap-amd64.sh
50 |
51 | ## About
52 |
53 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
54 |
55 |
56 |
57 | ## Licenses
58 |
59 | SPDX-License-Identifier: Apache-2.0
--------------------------------------------------------------------------------
/simple-talker-dl-py/README.md:
--------------------------------------------------------------------------------
1 | # ROS 2 Talker of a ctrlX Data Layer Value (Python)
2 |
3 | ## Introduction
4 |
5 | This project implements a ROS 2 talker, which reads a ctrlX Data Layer value and publishes it as ROS 2 message.
6 |
7 | [Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-python) was used as template.
8 |
9 | See also:
10 |
11 | * [Canonical Snapcraft - Deploying robotics applications](https://snapcraft.io/docs/robotics)
12 | * [Canonical - How to build a snap using ROS 2 Humble](https://canonical.com/blog/how-to-build-a-snap-using-ros-2-humble)
13 |
14 | ## Implementation
15 |
16 | * The directory structure is according colcon packages.
17 | * In `setup.py` and `setup.cfg` the [colcon](https://colcon.readthedocs.io/en/released/) package is defined.
18 | * `src/talker/talker/main.py` provides the main function
19 | * `src/talker/ros2/datalayer_reader_ros2_publisher.py` reads a ctrlX Data Layer value, creates a ROS 2 message and publishes it under the topic `ctrlXCpuUtilisationPercent`.
20 | * `src/talker/ctrlx_datalayer/ctrlx_datalayer_helper.py` contains helper functions regarding ctrlX Data Layer
21 | * `snap/snapcraft.yaml` defines which files are packed into the snap.
22 |
23 | ## Build process
24 |
25 | To build a snap run
26 |
27 | ./build-snap-amd64.sh
28 |
29 | The script contains following build steps:
30 |
31 | 1. Build the colcon package:
32 |
33 | colcon build
34 |
35 | 2. Clean the snapcraft helper directories:
36 |
37 | snapcraft clean --destructive-mode
38 |
39 | 3. Update helper directories and build the snap:
40 |
41 | snapcraft --destructive-mode
42 |
43 | Hint: Arm64-cross-build is not supported.
44 |
45 | ## Installation and test
46 |
47 | The `ros2-base` snap must already be installed.
48 |
49 | Install the created snap on ctrlX OS.
50 |
51 | It publishes at the ROS 2 topic `MinimalPublisher`.
52 |
53 | The output can be checked with:
54 |
55 | sudo snap logs -f ros2-simple-talker
56 |
57 | ## Build, install and test
58 |
59 | With following command you can combine the build, installation and test steps - here the target is a ctrlX COREvirtual with port forwarding.
60 |
61 | ../../../public/scripts/build-upload-log-snap.sh -PF
62 |
63 | ## About
64 |
65 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
66 |
67 |
68 |
69 | ## Licenses
70 |
71 | SPDX-License-Identifier: Apache-2.0
72 |
--------------------------------------------------------------------------------
/simple-talker-py/README.md:
--------------------------------------------------------------------------------
1 | # ROS 2 Simple Talker (Python)
2 |
3 | ## Introduction
4 |
5 | This project implements a simple ROS 2 talker, derived from [Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-python).
6 |
7 | The differences to this template project are:
8 |
9 | * ROS 2 runtime functions are provided by the `ros2-base` snap, which must be preinstalled on the ctrlX.
10 | * The project files are packed into a snap.
11 |
12 | See also:
13 |
14 | * [Canonical Snapcraft - Deploying robotics applications](https://snapcraft.io/docs/robotics)
15 | * [Canonical - How to build a snap using ROS 2 Humble](https://canonical.com/blog/how-to-build-a-snap-using-ros-2-humble)
16 |
17 | ## Implementation
18 |
19 | * The directory structure is according colcon packages.
20 | * In `setup.py` and `setup.cfg` the [colcon](https://colcon.readthedocs.io/en/released/) package is defined.
21 | * The one and only Python script is `main_minimal_subscriber.py`, stored in the directory `src/listener/listener/`
22 | * It contains the main function and a class `MinimalSubscriber`, derived from `rclpy.node.Node`
23 | * `snap/snapcraft.yaml` defines which files are packed into the snap.
24 |
25 | ## Build Process
26 |
27 | To build a snap run
28 |
29 | ./build-snap-amd64.sh
30 |
31 | The script contains following build steps:
32 |
33 | 1. Build the colcon package:
34 |
35 | colcon build
36 |
37 | 2. Clean the snapcraft helper directories:
38 |
39 | snapcraft clean --destructive-mode
40 |
41 | 3. Update helper directories and build the snap:
42 |
43 | snapcraft --destructive-mode
44 |
45 | Hint: To keep the project simple the arm64-cross-build is not supported.
46 |
47 | ## Installation and Test
48 |
49 | The `ros2-base` snaps must already be installed.
50 |
51 | Install the created snap on ctrlX OS.
52 |
53 | It publishes at the ROS 2 topic `MinimalPublisher`.
54 |
55 | The output can be checked with:
56 |
57 | sudo snap logs -f ros2-simple-talker
58 |
59 | ## Build, install and test
60 |
61 | With following command you can combine the build, installation and test steps - here the target is a ctrlX COREvirtual with port forwarding.
62 |
63 | ../../../public/scripts/build-upload-log-snap.sh -PF
64 |
65 | ## About
66 |
67 | SPDX-FileCopyrightText: Copyright (c) 2024 Bosch Rexroth AG
68 |
69 |
70 |
71 | ## Licenses
72 |
73 | SPDX-License-Identifier: MIT
74 |
--------------------------------------------------------------------------------
/ros2-base-humble-deb/README.md:
--------------------------------------------------------------------------------
1 | # ROS 2 Humble on ctrlX OS: A Snap Implementation of the ROS 2 Humble Distribution using ROS 2 Debian Package
2 |
3 | ## Introduction
4 |
5 | We recommend for ROS 2 applications running on a ctrlX OS this approach:
6 |
7 | * Build and install a __base snap__ containing the ROS 2 runtime and the components used for the ctrlX Data Layer access.
8 | * This base snap provides its components using the snap [content interface](https://snapcraft.io/docs/content-interface).
9 | * Pack your ROS 2 application into one or more overlay snaps.
10 | * Let these overlay snap use the ROS 2 runtime and the ctrlX Data Layer via the content interface of the __base snap__.
11 |
12 | This documentation describes how the base snap `ros2-base` can be build.
13 |
14 | !!! important
15 | The build for arm64 devices uses Docker and is in an unreleased state!
16 |
17 | ## Content of the Base Snap
18 |
19 | The file `snap/snapcraft.yaml` defines how the base snap will be build.
20 |
21 | ### Debian Packages
22 |
23 | The snapcraft plugin [colcon](https://snapcraft.io/docs/colcon-plugin) is used to download Debian packages:
24 |
25 | * Needed during build process: make, gcc, g++
26 | * Needed at runtime: software-properties-common, ros-humble-ros-base, python3-argcomplete, ca-certificates, ctrlx-datalayer
27 |
28 | ### Python Wheels
29 |
30 | The snapcraft plugin [python](https://snapcraft.io/docs/python-plugin) is used to download python wheels:
31 |
32 | * python3-wheel
33 | * ctrlx-datalayer
34 | * empy
35 | * numpy
36 | * rosdep
37 | * rosdistro
38 | * colcon-core
39 | * lark rosdep
40 | * rosdistro
41 | * colcon-core
42 | * lark
43 |
44 | ### Content Interface
45 |
46 | The base snap makes its files available via the content interface `executables`.
47 |
48 | ## Building the Base Snap
49 |
50 | ### AMD64
51 |
52 | Compiling for AMD64 on an AMD64 machine is straight-forward. Apart from the `snap/snapcraft.yaml` file and a shell script that calls snapcraft, nothing else is needed here.
53 |
54 | Call:
55 |
56 | ./build-snap-amd64.sh
57 |
58 | ### ARM64
59 |
60 | We recommend using a native ARM64 host environment to compile the ARM64 code. Set up a corresponding hardware, for example __Raspberry Pi__ or a virtual environment, for example __Qemu__ [installation scripts](https://github.com/boschrexroth/ctrlx-automation-sdk/tree/main/scripts/environment).
61 |
62 | ## About
63 |
64 | SPDX-FileCopyrightText: Copyright (c) 2023-2025 Bosch Rexroth AG
65 |
66 |
67 |
68 | ## Licenses
69 |
70 | SPDX-License-Identifier: MIT
71 |
--------------------------------------------------------------------------------
/simple-listener-py/README.md:
--------------------------------------------------------------------------------
1 | # ROS 2 Simple Listener (Python)
2 |
3 | ## Introduction
4 |
5 | This project implements a simple ROS 2 listener, derived from [Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-python).
6 |
7 | The differences to this template project are:
8 |
9 | * ROS 2 runtime functions are provided by the `ros2-base` snap, which must be preinstalled on the ctrlX.
10 | * The project files are packed into a snap.
11 |
12 | See also:
13 |
14 | * [Canonical Snapcraft - Deploying robotics applications](https://snapcraft.io/docs/robotics)
15 | * [Canonical - How to build a snap using ROS 2 Humble](https://canonical.com/blog/how-to-build-a-snap-using-ros-2-humble)
16 |
17 | ## Implementation
18 |
19 | * The directory structure is according colcon packages.
20 | * In `setup.py` and `setup.cfg` the [colcon](https://colcon.readthedocs.io/en/released/) package is defined.
21 | * The one and only Python script is `main_minimal_subscriber.py`, stored in the directory `src/listener/listener/`
22 | * It contains the main function and a class `MinimalSubscriber`, derived from `rclpy.node.Node`
23 | * `snap/snapcraft.yaml` defines which files are packed into the snap.
24 |
25 | ## Build Process
26 |
27 | To build a snap run
28 |
29 | ./build-snap-amd64.sh
30 |
31 | The script contains following build steps:
32 |
33 | 1. Build the colcon package:
34 |
35 | colcon build
36 |
37 | 2. Clean the snapcraft helper directories:
38 |
39 | snapcraft clean --destructive-mode
40 |
41 | 3. Update helper directories and build the snap:
42 |
43 | snapcraft --destructive-mode
44 |
45 | Hint: To keep the project simple the arm64-cross-build is not supported.
46 |
47 | ## Installation and Test
48 |
49 | Following snaps must already be installed:
50 |
51 | * `ros2-base`
52 | * `ros2-simple-talker`
53 |
54 | Install the created snap on a ctrlX OS.
55 |
56 | It listens at the ROS 2 topic `MinimalPublisher`.
57 |
58 | The output can be checked with:
59 |
60 | sudo snap logs -f ros2-simple-listener
61 |
62 | ## Build, install and test
63 |
64 | With following command you can combine the build, installation and test steps - here the target is a ctrlX COREvirtual with port forwarding.
65 |
66 | ../../../public/scripts/build-upload-log-snap.sh -PF
67 |
68 | ## About
69 |
70 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
71 |
72 |
73 |
74 | ## Licenses
75 |
76 | SPDX-License-Identifier: Apache-2.0
77 |
78 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/src/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(app)
3 | set(TARGET_PROJECT_NAME listener)
4 |
5 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
6 | add_compile_options(-Wall -Wextra -Wpedantic -Wno-unused-parameter -Wno-unused-function)
7 | endif()
8 |
9 | ###############################################################################
10 | # SHM as Default transport
11 | ###############################################################################
12 | option(SHM_TRANSPORT_DEFAULT "Add SHM transport to the default transports" OFF) # -> "Permission denied -> Function compute_per_allocation_extra_size"
13 |
14 | # find dependencies
15 | find_package(ament_cmake REQUIRED)
16 | find_package(rclcpp REQUIRED)
17 | find_package(std_msgs REQUIRED)
18 |
19 |
20 | #
21 | # Set link directories
22 | #
23 | MESSAGE( STATUS "Libraries directory: ${LIBRARY_DIR}")
24 | link_directories(
25 | ${LIBRARY_DIR}
26 | ${LIBRARY_DEP_DIR}
27 | )
28 |
29 | # User dependency directory
30 | #
31 | set (USER_DEPENDENCY_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
32 |
33 | SET ( PRIVATE_INCLUDE_DIRS
34 | ${CMAKE_CURRENT_LIST_DIR}
35 | ${CMAKE_CURRENT_BINARY_DIR}
36 | ${CMAKE_CURRENT_LIST_DIR}/include
37 | ${USER_DEPENDENCY_DIR}/include
38 | ${USER_DEPENDENCY_DIR}/include/comm.datalayer
39 | )
40 |
41 | # Set target link libraries
42 |
43 |
44 | if(BUILD_TESTING)
45 | find_package(ament_lint_auto REQUIRED)
46 | # the following line skips the linter which checks for copyrights
47 | # comment the line when a copyright and license is added to all source files
48 | set(ament_cmake_copyright_FOUND TRUE)
49 | # the following line skips cpplint (only works in a git repo)
50 | # comment the line when this package is in a git repo and when
51 | # a copyright and license is added to all source files
52 | set(ament_cmake_cpplint_FOUND TRUE)
53 | ament_lint_auto_find_test_dependencies()
54 | endif()
55 |
56 | add_executable(listener src/subscriber_member_function.cpp)
57 | ament_target_dependencies(listener rclcpp std_msgs)
58 |
59 |
60 | #
61 | # Set target include directories
62 | #
63 | target_include_directories ( ${TARGET_PROJECT_NAME}
64 | PUBLIC ${PUBLIC_INCLUDE_DIRS}
65 | PUBLIC ${LIBRARY_INCLUDES}
66 | PRIVATE ${PRIVATE_INCLUDE_DIRS}
67 | )
68 | #
69 | target_link_libraries(${TARGET_PROJECT_NAME} -Wl,--no-undefined)
70 | target_link_libraries(${TARGET_PROJECT_NAME}
71 | libcomm_datalayer.so
72 | pthread
73 | # systemd
74 | # zmq
75 | ssl
76 | crypto
77 | )
78 |
79 | install(TARGETS
80 | listener
81 | DESTINATION lib/${PROJECT_NAME})
82 |
83 | ament_package()
84 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/README.md:
--------------------------------------------------------------------------------
1 | # Simple ROS 2 Subscriber in C++
2 |
3 | A simple ROS 2 node which cyclically reads the CPU usage from the ctrlX Data Layer by reading the address `framework/metrics/system/cpu-utilisation-percent` and pushes on the ROS2 topic `ros2_simple_talker_cpp`.
4 | In the ctrlX Data Layer you can find any kind of information about the device, process, fieldbus and periphery.
5 | Please note, that this is a very basic example which uses the simplest method of reading in the ctrlX Data Layer. For improved performance and scalability you should consider creating a subscription instead of performing synchronuous (blocking) reads.
6 |
7 | ## Prerequisites
8 |
9 | * `ros-base` snap. The base snap which provides the ROS 2 runtime binaries. Has to be installed on ctrlX OS. See [ROS 2 Humble Base Snap](../ros2-base-humble-deb/README.md).
10 | * An Ubuntu based build environment to build an app. See [ctrlX Automation SDK](https://github.com/boschrexroth/ctrlx-automation-sdk).
11 |
12 | ## Basis for this Project
13 |
14 | This project is based on the official ROS 2 Tutorial: [Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-c).
15 |
16 | ## Building a Snap
17 |
18 | Building a snap has two steps:
19 |
20 | 1. Colcon build: `CMakeLists.txt` defines how compile and link the C++ sources.
21 | 2. snap build: `snap/snapcraft.yaml` defines how the compiled binaries are packed into the snap and how they are called on ctrlX OS.
22 |
23 | ### Colcon Configuration
24 |
25 | The colcon build tool is configured by `CMakeLists.txt`.
26 |
27 | This section defines the ROS 2 packages needed:
28 |
29 | find_package(ament_cmake REQUIRED)
30 | find_package(rclcpp REQUIRED)
31 | find_package(std_msgs REQUIRED)
32 |
33 | And here the executables and their dependencies are defined:
34 |
35 | add_executable(listener src/subscriber_member_function.cpp)
36 | ament_target_dependencies(listener rclcpp std_msgs)
37 |
38 | ### Snapcraft Configuration
39 |
40 | `snap/snapcraft.yaml` defines how the snap will be build:
41 |
42 | * `install/` is dumped into the snap
43 | * also `wrapper/`
44 | * Two apps (talker and listener) are copied into the snap and started as services
45 | * The snap - respectively the executables - uses the content interface of the `ros-base` snap (here the ROS 2 runtime is provided).
46 |
47 | ### Build the Snap
48 |
49 | Start this script:
50 |
51 | ./build-snap-amd64.sh
52 |
53 | ## About
54 |
55 | SPDX-FileCopyrightText: Copyright (c) 2023 Bosch Rexroth AG
56 |
57 |
58 |
59 | ## Licenses
60 |
61 | SPDX-License-Identifier: Apache-2.0
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/ctrlx_datalayer/ctrlx_provider_node.py:
--------------------------------------------------------------------------------
1 | """Provides a ctrlX Data Layer node to store the received ROS 2 value."""
2 |
3 | # SPDX-FileCopyrightText: Bosch Rexroth AG
4 | #
5 | # SPDX-License-Identifier: MIT
6 |
7 | import ctrlxdatalayer
8 | from ctrlxdatalayer.provider import Provider
9 | from ctrlxdatalayer.provider_node import ProviderNode, ProviderNodeCallbacks, NodeCallback
10 | from ctrlxdatalayer.variant import Result, Variant
11 |
12 |
13 | class CtrlXProviderNode:
14 | """
15 | Class CtrlXProviderNode.
16 |
17 | Provides a ctrlX Data Layer node and handles all events via callback functions.
18 | """
19 |
20 | def __init__(self,
21 | datalayer_provider: Provider,
22 | address: str,
23 | variant: Variant):
24 | """Initialize the instance."""
25 | self.cbs = ProviderNodeCallbacks(
26 | self.__on_create,
27 | self.__on_remove,
28 | self.__on_browse,
29 | self.__on_read,
30 | self.__on_write,
31 | self.__on_metadata
32 | )
33 |
34 | self.providerNode = ProviderNode(self.cbs)
35 |
36 | self.provider = datalayer_provider
37 | self.address = address
38 | self.variant = variant
39 |
40 | def register_node(self):
41 | """Register the node."""
42 | return self.provider.register_node(self.address, self.providerNode)
43 |
44 | def unregister_node(self):
45 | """Unregister the node."""
46 | self.provider.unregister_node(self.address)
47 |
48 | def set_value(self, value: Variant):
49 | """Set the value."""
50 | self.variant = value
51 |
52 | def __on_create(self, userdata: ctrlxdatalayer.clib.userData_c_void_p,
53 | address: str, data: Variant, cb: NodeCallback):
54 | """Handle on_create event."""
55 | print('__on_create()', 'address:', address, 'userdata:', userdata)
56 | cb(Result.OK, data)
57 |
58 | def __on_remove(self, userdata: ctrlxdatalayer.clib.userData_c_void_p,
59 | address: str, cb: NodeCallback):
60 | """Handle on_remove event."""
61 | print('__on_remove()', 'address:', address, 'userdata:', userdata)
62 | cb(Result.UNSUPPORTED, None)
63 |
64 | def __on_browse(self,
65 | userdata: ctrlxdatalayer.clib.userData_c_void_p,
66 | address: str,
67 | cb: NodeCallback):
68 | """Handle on_browse event."""
69 | variant = Variant()
70 | variant.set_array_string([])
71 | cb(Result.OK, variant)
72 |
73 | def __on_read(self, userdata: ctrlxdatalayer.clib.userData_c_void_p,
74 | address: str, data: Variant, cb: NodeCallback):
75 | """Handle on_read event."""
76 | variant = self.variant
77 | cb(Result.OK, variant)
78 |
79 | def __on_write(self, userdata: ctrlxdatalayer.clib.userData_c_void_p,
80 | address: str, data: Variant, cb: NodeCallback):
81 | """Handle on_write event."""
82 | cb(Result.UNSUPPORTED, None)
83 |
84 | def __on_metadata(self, userdata: ctrlxdatalayer.clib.userData_c_void_p,
85 | address: str,
86 | cb: NodeCallback):
87 | """Handle on_metadata event."""
88 | cb(Result.FAILED, None)
89 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | Please follow the Code of Conduct in all interactions with this project.
4 |
5 | ## Our Pledge
6 |
7 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
8 |
9 | ## Our Standards
10 |
11 | Examples of behavior that contributes to creating a positive environment include:
12 |
13 | * Using welcoming and inclusive language
14 | * Being respectful of differing viewpoints and experiences
15 | * Gracefully accepting constructive criticism
16 | * Focusing on what is best for the community
17 | * Showing empathy towards other community members
18 |
19 | Examples of unacceptable behavior by participants include:
20 |
21 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
22 | * Trolling, insulting/derogatory comments, and personal or political attacks
23 | * Public or private harassment
24 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
25 | * Other conduct which could reasonably be considered inappropriate in a professional setting
26 |
27 | ## Our Responsibilities
28 |
29 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
30 |
31 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
32 |
33 | ## Scope
34 |
35 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
36 |
37 | ## Enforcement
38 |
39 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
40 |
41 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
42 |
43 | ## Attribution
44 |
45 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
46 |
47 | [homepage]: http://contributor-covenant.org
48 | [version]: http://contributor-covenant.org/version/1/4/
49 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/ros2/ros2_listener_ctrlx_provider.py:
--------------------------------------------------------------------------------
1 | """Listens for ROS 2 messages and stores them into the ctrlX Data Layer."""
2 |
3 | # SPDX-FileCopyrightText: Bosch Rexroth AG
4 | #
5 | # SPDX-License-Identifier: MIT
6 |
7 | import rclpy
8 | from rclpy.node import Node
9 |
10 | import std_msgs.msg
11 |
12 | import ctrlxdatalayer
13 | from ctrlxdatalayer.variant import Result, Variant
14 |
15 | from ctrlx_datalayer.ctrlx_datalayer_helper import get_provider
16 | from ctrlx_datalayer.ctrlx_provider_node import CtrlXProviderNode
17 |
18 |
19 | class Ros2ListenerDataLayerProvider(Node):
20 | """
21 | Class Ros2ListenerDataLayerProvider.
22 |
23 | Receives ROS 2 messages and stores the received values into a ctrlX Data Layer node.
24 | """
25 |
26 | def __init__(self, dl_address, ros2_topic):
27 | """Initialize the instance."""
28 | self.dl_address = dl_address
29 | self.ros2_topic = ros2_topic
30 |
31 | self.datalayer_system = None
32 | self.datalayer_provider = None
33 | self.variant = Variant()
34 | self.provider_node = None
35 |
36 | self.ros2_subscription = None
37 | self.ros2_msg_data = None
38 |
39 | def read_data_layer_value(self):
40 | """Read the value from the ctrlX Data Layer."""
41 | print('INFO Reading ctrlX Data Layer node', self.dl_address, ' - BEGIN')
42 | result, variant = self.datalayer_provider.read_sync(self.dl_address)
43 | print('INFO Reading ctrlX Data Layer node', self.dl_address, ' - END')
44 | if result != Result.OK:
45 | print('ERROR Reading ctrlX Data Layer node', self.dl_address, 'failed', result)
46 | return None
47 |
48 | print('INFO Data type ', variant.get_type().name)
49 | return variant
50 |
51 | def start(self):
52 | """Start the activity."""
53 | self.datalayer_system = ctrlxdatalayer.system.System('')
54 | self.datalayer_system.start(False)
55 |
56 | print('INFO Creating ctrlX Data Layer connnection')
57 | self.datalayer_provider, connection_string = get_provider(self.datalayer_system)
58 | if self.datalayer_provider is None:
59 | print('ERROR Creating ctrlX Data Layer connnection to', connection_string, 'failed')
60 | return False
61 | self.datalayer_provider.start()
62 |
63 | self.variant.set_float64(-1.0)
64 | self.provider_node = CtrlXProviderNode(self.datalayer_provider, self.dl_address, self.variant)
65 | result = self.provider_node.register_node()
66 | if result != Result.OK:
67 | print('ERROR Registering', self.dl_address, 'failed')
68 | return False
69 |
70 | print('INFO Initializing ROS 2 node Ros2ListenerCtrlxProvider')
71 | super().__init__('Ros2ListenerCtrlxProvider')
72 |
73 | print('INFO Creating ROS 2 listener to topic', self.ros2_topic)
74 | self.ros2_subscription = self.create_subscription(std_msgs.msg.Float64, self.ros2_topic, self.listener_callback, 10)
75 | if self.ros2_subscription is None:
76 | print('ERROR Creating ROS 2 subscription failed')
77 | return False
78 |
79 | return True
80 |
81 | def listener_callback(self, msg):
82 | """Get the ROS 2 message data and store it into ctrlX Data Layer."""
83 | self.get_logger().info('Received "%s"' % msg.data)
84 | self.ros2_msg_data = msg.data
85 | self.variant.set_float64(msg.data)
86 | self.provider_node.set_value(self.variant)
87 |
88 | def stop(self):
89 | """Stop the activity."""
90 | self.datalayer_system = ctrlxdatalayer.system.System('')
91 | self.datalayer_system.stop(False)
92 |
93 | if self.timer is not None:
94 | self.destroy_timer(self.timer)
95 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/ctrlx_datalayer/ctrlx_datalayer_helper.py:
--------------------------------------------------------------------------------
1 | """
2 | Helper script to connect to ctrlX Data Layer.
3 |
4 | This script provides auxiliary methods to create ctrlX Datalayer client and
5 | provider connections to ctrlX CORE devices.
6 |
7 | It can be used for both running in an app build environment (QEMU VM) and
8 | within the snap environment on the ctrlX CORE.
9 |
10 | Feel free to use it in your projects and to change it if necessary.
11 |
12 | For ease of use, the default values for IP address, user, password and SSL
13 | port are chosen to match the settings of a newly created ctrlX CORE device:
14 |
15 | ip='192.168.1.1'
16 | user='boschrexroth'
17 | password='boschrexroth'
18 | ssl_port=443
19 |
20 | If these values do not suit your use case, explicitly pass the parameters that
21 | require different values.
22 |
23 | Here some examples:
24 |
25 | 1. ctrlX CORE or ctrlX COREvirtual with another IP address, user and password:
26 |
27 | client, client_connection = get_client(system, ip='192.168.1.100',
28 | user='admin', password='-$_U/{X$aG}Z3/e<')
29 |
30 | 2. ctrlX COREvirtual with port forwarding running on the same host as the app
31 | build environment (QEMU VM):
32 |
33 | client, client_connection =
34 | get_client(system, ip='10.0.2.2', ssl_port=8443)
35 |
36 | Remarks:
37 | 10.0.2.2 is the IP address of the host from the point of view of the app
38 | build environment (QEMU VM).
39 | 8443 is the host port which is forwarded to the SSL port (=433) of the
40 | ctrlX COREvirtual
41 |
42 |
43 | IMPORTANT:
44 | You need not change the parameter settings before building a snap and
45 | installing the snap on a ctrlX CORE.
46 | The method get_connection_string detects the snap environment and uses
47 | automatically inter process communication.
48 |
49 | Therefor the connection string to the ctrlX Datalayer is:
50 |
51 | 'ipc://'
52 |
53 | """
54 |
55 | # SPDX-FileCopyrightText: Bosch Rexroth AG
56 | #
57 | # SPDX-License-Identifier: MIT
58 |
59 | import os
60 |
61 | import ctrlxdatalayer
62 |
63 |
64 | def get_connection_string(
65 | ip='192.168.1.1',
66 | user='boschrexroth',
67 | password='boschrexroth',
68 | ssl_port=443):
69 | """
70 | Combine a ctrlX Datalayer connection string.
71 |
72 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
73 | @param[in] user Name of the user.
74 | @param[in] password Password of the user.
75 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
76 | @returns connection_string The connection string: 'ipc://' for running in snap environment, 'tcp://...' for running in environment.
77 | """
78 | if 'SNAP' in os.environ:
79 | return 'ipc://'
80 |
81 | # Client connection port 2069 resp. Provider connection port 2070 are obsolete
82 | connection_string = 'tcp://'+user+':'+password+'@'+ip
83 |
84 | if (ssl_port == 443):
85 | return connection_string
86 |
87 | return connection_string+'?sslport=' + str(ssl_port)
88 |
89 |
90 | def get_client(system: ctrlxdatalayer.system.System,
91 | ip='192.168.1.1',
92 | user='boschrexroth',
93 | password='boschrexroth',
94 | ssl_port=8443):
95 | """
96 | Create a ctrlX Datalayer client instance.
97 |
98 | @param[in] system A ctrlxdatalayer.system.System instance
99 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
100 | @param[in] user Name of the user.
101 | @param[in] password Password of the user.
102 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
103 | @returns tuple (client, connection_string)
104 | @return The ctrlxdatalayer.client.Client instance or None if failed
105 | @return The connection string or None if failed
106 | """
107 | connection_string = get_connection_string(
108 | ip, user, password, ssl_port)
109 | client = system.factory().create_client(connection_string)
110 | if client.is_connected():
111 | return client, connection_string
112 | client.close()
113 |
114 | return None, connection_string
115 |
116 |
117 | def get_provider(system: ctrlxdatalayer.system.System,
118 | ip='192.168.1.1',
119 | user='boschrexroth',
120 | password='boschrexroth',
121 | ssl_port=443):
122 | """
123 | Create a ctrlX Datalayer provider instance.
124 |
125 | @param[in] system A ctrlxdatalayer.system.System instance
126 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
127 | @param[in] user Name of the user.
128 | @param[in] password Password of the user.
129 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
130 | @returns tuple (provider, connection_string)
131 | @return , a ctrlxdatalayer.provider.Provider instance or None if failed,
132 | @return , a connection string or None if failed
133 | """
134 | connection_string = get_connection_string(
135 | ip, user, password, ssl_port)
136 | provider = system.factory().create_provider(connection_string)
137 | if (provider.start() == ctrlxdatalayer.variant.Result.OK) & provider.is_connected():
138 | return provider, connection_string
139 | provider.close()
140 |
141 | return None, connection_string
142 |
--------------------------------------------------------------------------------
/simple-listener-dl-py/src/app/ctrlx_datalayer/ctrlx_datalayer_helper.py:
--------------------------------------------------------------------------------
1 | """
2 | Helper script to connect to ctrlX Data Layer.
3 |
4 | This script provides auxiliary methods to create ctrlX Datalayer client and
5 | provider connections to ctrlX CORE devices.
6 |
7 | It can be used for both running in an app build environment (QEMU VM) and
8 | within the snap environment on the ctrlX CORE.
9 |
10 | Feel free to use it in your projects and to change it if necessary.
11 |
12 | For ease of use, the default values for IP address, user, password and SSL
13 | port are chosen to match the settings of a newly created ctrlX CORE device:
14 |
15 | ip='192.168.1.1'
16 | user='boschrexroth'
17 | password='boschrexroth'
18 | ssl_port=443
19 |
20 | If these values do not suit your use case, explicitly pass the parameters that
21 | require different values.
22 |
23 | Here some examples:
24 |
25 | 1. ctrlX CORE or ctrlX COREvirtual with another IP address, user and password:
26 |
27 | client, client_connection = get_client(system, ip='192.168.1.100',
28 | user='admin', password='-$_U/{X$aG}Z3/e<')
29 |
30 | 2. ctrlX COREvirtual with port forwarding running on the same host as the app
31 | build environment (QEMU VM):
32 |
33 | client, client_connection =
34 | get_client(system, ip='10.0.2.2', ssl_port=8443)
35 |
36 | Remarks:
37 | 10.0.2.2 is the IP address of the host from the point of view of the app
38 | build environment (QEMU VM).
39 | 8443 is the host port which is forwarded to the SSL port (=433) of the
40 | ctrlX COREvirtual
41 |
42 |
43 | IMPORTANT:
44 | You need not change the parameter settings before building a snap and
45 | installing the snap on a ctrlX CORE.
46 | The method get_connection_string detects the snap environment and uses
47 | automatically inter process communication.
48 |
49 | Therefor the connection string to the ctrlX Datalayer is:
50 |
51 | 'ipc://'
52 |
53 | """
54 |
55 | # SPDX-FileCopyrightText: Bosch Rexroth AG
56 | #
57 | # SPDX-License-Identifier: MIT
58 |
59 | import os
60 |
61 | import ctrlxdatalayer
62 |
63 |
64 | def get_connection_string(
65 | ip='192.168.1.1',
66 | user='boschrexroth',
67 | password='boschrexroth',
68 | ssl_port=443):
69 | """
70 | Combine a ctrlX Datalayer connection string.
71 |
72 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
73 | @param[in] user Name of the user.
74 | @param[in] password Password of the user.
75 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
76 | @returns connection_string The connection string: 'ipc://' for running in snap environment, 'tcp://...' for running in environment.
77 | """
78 | if 'SNAP' in os.environ:
79 | return 'ipc://'
80 |
81 | # Client connection port 2069 resp. Provider connection port 2070 are obsolete
82 | connection_string = 'tcp://'+user+':'+password+'@'+ip
83 |
84 | if (ssl_port == 443):
85 | return connection_string
86 |
87 | return connection_string+'?sslport=' + str(ssl_port)
88 |
89 |
90 | def get_client(system: ctrlxdatalayer.system.System,
91 | ip='192.168.1.1',
92 | user='boschrexroth',
93 | password='boschrexroth',
94 | ssl_port=8443):
95 | """
96 | Create a ctrlX Datalayer client instance.
97 |
98 | @param[in] system A ctrlxdatalayer.system.System instance
99 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
100 | @param[in] user Name of the user.
101 | @param[in] password Password of the user.
102 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
103 | @returns tuple (client, connection_string)
104 | @return The ctrlxdatalayer.client.Client instance or None if failed
105 | @return The connection string or None if failed
106 | """
107 | connection_string = get_connection_string(
108 | ip, user, password, ssl_port)
109 | client = system.factory().create_client(connection_string)
110 | if client.is_connected():
111 | return client, connection_string
112 | client.close()
113 |
114 | return None, connection_string
115 |
116 |
117 | def get_provider(system: ctrlxdatalayer.system.System,
118 | ip='192.168.1.1',
119 | user='boschrexroth',
120 | password='boschrexroth',
121 | ssl_port=443):
122 | """
123 | Create a ctrlX Datalayer provider instance.
124 |
125 | @param[in] system A ctrlxdatalayer.system.System instance
126 | @param[in] ip IP address of the ctrlX CORE. Use '10.0.2.2' to connect to a ctrlX COREvirtual with port forwarding.
127 | @param[in] user Name of the user.
128 | @param[in] password Password of the user.
129 | @param[in] ssl_port Port number for a SSL connection. ctrlX COREvirtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual.
130 | @returns tuple (provider, connection_string)
131 | @return , a ctrlxdatalayer.provider.Provider instance or None if failed,
132 | @return , a connection string or None if failed
133 | """
134 | connection_string = get_connection_string(
135 | ip, user, password, ssl_port)
136 | provider = system.factory().create_provider(connection_string)
137 | if (provider.start() == ctrlxdatalayer.variant.Result.OK) & provider.is_connected():
138 | return provider, connection_string
139 | provider.close()
140 |
141 | return None, connection_string
142 |
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/src/app/src/ctrlx_datalayer_helper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Bosch Rexroth AG
3 | *
4 | * SPDX-License-Identifier: MIT
5 | */
6 |
7 | #ifndef CTRLX_DATALAYER_HELPER_H
8 | #define CTRLX_DATALAYER_HELPER_H
9 |
10 | /*! \file
11 | *
12 | * This header file provides auxiliary methods to create ctrlX Datalayer client and provider connections to ctrlX CORE devices.
13 | * It can be used for both running in an app build environment (QEMU VM) and within the snap environment on the ctrlX CORE.
14 | *
15 | * Feel free to use it in your projects and to change it if necessary.
16 | *
17 | * For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a
18 | * newly created ctrlX CORE device:
19 | *
20 | * ip="192.168.1.1"
21 | * user="boschrexroth"
22 | * password="boschrexroth"
23 | * ssl_port=443
24 | *
25 | * If these values do not suit your use case, explicitly pass the parameters that require different values.
26 | * Here some examples:
27 | *
28 | * 1. ctrlX CORE or ctrlX COREvirtual with another IP address, user and password:
29 | *
30 | * client, client_connection = get_client(system, ip="192.168.1.100", user="admin", password="-$_U/{X$aG}Z3/e<")
31 | *
32 | * 2. ctrlX COREvirtual with port forwarding running on the same host as the app build environment (QEMU VM):
33 | *
34 | * client, client_connection = get_client(system, ip="10.0.2.2", ssl_port=8443)
35 | *
36 | * Remarks:
37 | * 10.0.2.2 is the IP address of the host from the point of view of the app build environment (QEMU VM).
38 | * 8443 is the host port which is forwarded to the SSL port (=433) of the ctrlX COREvirtual
39 | *
40 | *
41 | * IMPORTANT:
42 | * You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE.
43 | * The method get_connection_string detects the snap environment and uses automatically inter process communication.
44 | * Therefor the connection string to the ctrlX Datalayer is:
45 | *
46 | * "ipc://"
47 | *
48 | */
49 |
50 | #include
51 | #include
52 |
53 | #include "comm/datalayer/datalayer.h"
54 | #include "comm/datalayer/datalayer_system.h"
55 |
56 | //! Retrieve environment variable SNAP
57 | static const char* snapPath()
58 | {
59 | return std::getenv("SNAP");
60 | }
61 |
62 | //! Test if code is runnning in snap environment
63 | static bool isSnap()
64 | {
65 | return snapPath() != nullptr;
66 | }
67 |
68 | //! Get Datalayer connection string
69 | //! @param[in] ip IP address of the ctrlX CORE: 10.0.2.2 is ctrlX COREvirtual with port forwarding
70 | //! @param[in] user User name
71 | //! @param[in] password The password
72 | //! @param[in] sslPort The port number for SSL: 8443 if ctrlX COREvirtual with port forwarding 8443:443
73 | //! @result Connection string
74 | static std::string getConnectionString(
75 | const std::string& ip = "10.0.2.2",
76 | const std::string& user = "boschrexroth",
77 | const std::string& password = "boschrexroth",
78 | int sslPort = 8443)
79 | {
80 | if (isSnap())
81 | {
82 | std::cout << "INFO Is snap" << std::endl;
83 | return DL_IPC;
84 | }
85 |
86 | std::string connectionString = DL_TCP + user + std::string(":") + password + std::string("@") + ip;
87 |
88 | if (443 == sslPort)
89 | {
90 | return connectionString;
91 | }
92 |
93 | return connectionString + std::string("?sslport=") + std::to_string(sslPort);
94 | }
95 |
96 | //! Get Datalayer Client instance
97 | //! @param[in] datalayerSystem Datalayer.System instance
98 | //! @param[in] ip IP address of the ctrlX CORE: 10.0.2.2 is ctrlX COREvirtual with port forwarding
99 | //! @param[in] user User name
100 | //! @param[in] password The password
101 | //! @param[in] sslPort The port number for SSL: 8443 if ctrlX COREvirtual with port forwarding 8443:443
102 | //! @result IClient instance or nullptr on error
103 | static comm::datalayer::IClient* getClient(comm::datalayer::DatalayerSystem& datalayerSystem,
104 | const std::string& ip = "10.0.2.2",
105 | const std::string& user = "boschrexroth",
106 | const std::string& password = "boschrexroth", int sslPort = 8443)
107 | {
108 | std::string connectionString = getConnectionString(ip, user, password, sslPort);
109 | comm::datalayer::IClient* client = datalayerSystem.factory()->createClient(connectionString);
110 | if (client->isConnected())
111 | {
112 | return client;
113 | }
114 |
115 | delete client;
116 |
117 | return nullptr;
118 | }
119 |
120 | //! Get Datalayer Provider instance
121 | //! @param[in] datalayerSystem Datalayer.System instance
122 | //! @param[in] ip IP address of the ctrlX CORE: 10.0.2.2 is ctrlX COREvirtual with port forwarding
123 | //! @param[in] user User name
124 | //! @param[in] password The password
125 | //! @param[in] sslPort The port number for SSL: 8443 if ctrlX COREvirtual with port forwarding 8443:443
126 | //! @result IProvider instance or nullptr on error
127 | static comm::datalayer::IProvider* getProvider(comm::datalayer::DatalayerSystem& datalayerSystem,
128 | const std::string& ip = "10.0.2.2",
129 | const std::string& user = "boschrexroth",
130 | const std::string& password = "boschrexroth", int sslPort = 8443)
131 | {
132 | std::string connectionString = getConnectionString(ip, user, password, sslPort);
133 | comm::datalayer::IProvider* provider = datalayerSystem.factory()->createProvider(connectionString);
134 | if (provider->start() == DL_OK && provider->isConnected())
135 | {
136 | return provider;
137 | }
138 |
139 | delete provider;
140 |
141 | return nullptr;
142 | }
143 |
144 | #endif
145 |
--------------------------------------------------------------------------------
/simple-talker-dl-cpp/src/app/src/subscriber_member_function.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Open Source Robotics Foundation, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include
24 |
25 | #include "rclcpp/rclcpp.hpp"
26 | #include "std_msgs/msg/string.hpp"
27 |
28 | #include "comm/datalayer/datalayer.h"
29 | #include "comm/datalayer/datalayer_system.h"
30 |
31 | using namespace std::chrono_literals;
32 |
33 |
34 |
35 | // Add some signal Handling so we are able to abort the program with sending sigint
36 | static bool g_endProcess = false;
37 |
38 | static void signalHandler(int signal)
39 | {
40 | std::cout << "signal: " << signal << std::endl;
41 | g_endProcess = true;
42 | // Clean up datalayer instances so that process ends properly
43 | // Attention: Doesn't return if any provider or client instance is still runnning
44 |
45 | }
46 | //! Retrieve environment variable SNAP
47 | //! @result The content of SNAP ales nullptr if not available
48 | static const char* snapPath()
49 | {
50 | return std::getenv("SNAP");
51 | }
52 |
53 | //! Test if code is runnning in snap environment
54 | //! @result True if running snap environment
55 | static bool isSnap()
56 | {
57 | return snapPath() != nullptr;
58 | }
59 |
60 | //! Get Datalayer connection string
61 | //! @param[in] ip IP address of the ctrlX CORE: 10.0.2.2 is ctrlX COREvirtual with port forwarding
62 | //! @param[in] user User name
63 | //! @param[in] password The password
64 | //! @param[in] sslPort The port number for SSL: 8443 if ctrlX COREvirtual with port forwarding 8443:443
65 | //! @result Connection string
66 | static std::string getConnectionString(
67 | const std::string& ip = "10.0.2.2",
68 | const std::string& user = "boschrexroth",
69 | const std::string& password = "boschrexroth",
70 | int sslPort = 8443)
71 | {
72 | if (isSnap())
73 | {
74 | return DL_IPC;
75 | }
76 |
77 | std::string connectionString = DL_TCP + user + std::string(":") + password + std::string("@") + ip;
78 |
79 | if (443 == sslPort)
80 | {
81 | return connectionString;
82 | }
83 |
84 | return connectionString + std::string("?sslport=") + std::to_string(sslPort);
85 | }
86 |
87 | class MinimalPublisher : public rclcpp::Node
88 | {
89 | rclcpp::Publisher::SharedPtr m_publisher;
90 |
91 | public:
92 | MinimalPublisher()
93 | : Node("minimal_publisher")
94 | {
95 | m_publisher = this->create_publisher("ros2_simple_talker_cpp", 10);
96 | }
97 |
98 | /// @brief
99 | void myprint(const std::string& input)
100 |
101 | {
102 | auto message = std_msgs::msg::String();
103 | message.data = "CPU Percentage: " + input;
104 | RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
105 | m_publisher->publish(message);
106 | }
107 | };
108 |
109 | int main(int argc, char * argv[])
110 | {
111 | std::signal(SIGINT, signalHandler);
112 | // Initialize ROS 2
113 | rclcpp::init(argc, argv);
114 | MinimalPublisher pippo;
115 |
116 | std::cout << "INFO Starting ctrlX Data Layer system (without broker)" << std::endl;
117 | comm::datalayer::DatalayerSystem datalayerSystem;
118 | datalayerSystem.start(false);
119 |
120 | auto connectionString = getConnectionString(); // default: ctrlX CORE or ctrlX COREvirtual with Network Adpater
121 | std::cout << "INFO Creating ctrlX Data Layer client connection to " << connectionString << " ..." << std::endl;
122 | auto dataLayerClient = datalayerSystem.factory()->createClient(connectionString);
123 |
124 | int counter = 1;
125 | while (dataLayerClient->isConnected() && g_endProcess == false)
126 | {
127 | std::cout << "Loop #" << counter++ << std::endl;
128 |
129 | //Synchronous read of a ctrlX Data Layer node with a simple data type
130 | auto cpuUtilisationPercentAddress = "framework/metrics/system/cpu-utilisation-percent";
131 | comm::datalayer::Variant cpuUtilisationPercentValue;
132 | std::cout << "INFO Reading " << cpuUtilisationPercentAddress << " synchronously..." << std::endl;
133 | auto result = dataLayerClient->readSync(cpuUtilisationPercentAddress, &cpuUtilisationPercentValue);
134 | if (result != DL_OK){
135 | std::cout <<"WARN Reading " << cpuUtilisationPercentAddress << " failed with: " << result.toString() << std::endl;
136 | }
137 | else
138 | {
139 | if (cpuUtilisationPercentValue.getType() == comm::datalayer::VariantType::FLOAT64)
140 | {
141 | std::cout << "INFO Value of " << cpuUtilisationPercentAddress << ": " << double(cpuUtilisationPercentValue) << " %" << std::endl;
142 | auto str = std::to_string(double(cpuUtilisationPercentValue));
143 | pippo.myprint(str);
144 | }
145 | else
146 | {
147 | std::cout << "WARN Value of " << cpuUtilisationPercentAddress << " has unexpected type: " << cpuUtilisationPercentValue.typeAsString() << std::endl;
148 | }
149 | }
150 |
151 | std::cout << "INFO Sleeping..." << std::endl;
152 | sleep(2);
153 | }
154 |
155 | std::cout << "ERROR ctrlX Data Layer connection is broken" << std::endl;
156 |
157 | delete dataLayerClient;
158 | datalayerSystem.stop();
159 |
160 | return 1; // We exit because an error happend
161 | }
--------------------------------------------------------------------------------
/simple-listener-dl-cpp/src/app/src/subscriber_member_function.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Open Source Robotics Foundation, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #include "rclcpp/rclcpp.hpp"
25 | #include "std_msgs/msg/string.hpp"
26 |
27 | #include "comm/datalayer/datalayer.h"
28 | #include "comm/datalayer/datalayer_system.h"
29 |
30 | #include "ctrlx_datalayer_helper.h"
31 |
32 | using std::placeholders::_1;
33 |
34 |
35 | using comm::datalayer::IProviderNode;
36 |
37 | // Basic class Provider node interface for providing data to the system
38 | class MyProviderNode: public IProviderNode
39 | {
40 | private:
41 | comm::datalayer::Variant m_data;
42 |
43 | public:
44 | MyProviderNode(comm::datalayer::Variant data)
45 | : m_data(data)
46 | {};
47 | void setString(const std::string& input)
48 | {
49 | m_data.setValue(input);
50 |
51 | }
52 | virtual ~MyProviderNode() override {};
53 |
54 | // Create function of an object. Function will be called whenever a object should be created.
55 | virtual void onCreate(const std::string& address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
56 | {
57 | callback(comm::datalayer::DlResult::DL_FAILED, nullptr);
58 | }
59 |
60 | // Read function of a node. Function will be called whenever a node should be read.
61 | virtual void onRead(const std::string& address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
62 | {
63 | comm::datalayer::Variant dataRead;
64 | dataRead = m_data;
65 | callback(comm::datalayer::DlResult::DL_OK, &dataRead);
66 | }
67 |
68 | // Write function of a node. Function will be called whenever a node should be written.
69 | virtual void onWrite(const std::string& address, const comm::datalayer::Variant* data, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
70 | {
71 | std::cout << "INFO onWrite " << address << std::endl;
72 |
73 | if (data->getType() != m_data.getType())
74 | {
75 | callback(comm::datalayer::DlResult::DL_TYPE_MISMATCH, nullptr);
76 | }
77 |
78 | m_data = *data;
79 | callback(comm::datalayer::DlResult::DL_OK, data);
80 | }
81 |
82 | // Remove function for an object. Function will be called whenever a object should be removed.
83 | virtual void onRemove(const std::string& address, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
84 | {
85 | callback(comm::datalayer::DlResult::DL_FAILED, nullptr);
86 | }
87 |
88 | // Browse function of a node. Function will be called to determine children of a node.
89 | virtual void onBrowse(const std::string& address, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
90 | {
91 | callback(comm::datalayer::DlResult::DL_FAILED, nullptr);
92 | }
93 |
94 | // Read function of metadata of an object. Function will be called whenever a node should be written.
95 | virtual void onMetadata(const std::string& address, const comm::datalayer::IProviderNode::ResponseCallback& callback) override
96 | {
97 | // Keep this comment! Can be used as sample creating metadata programmatically.
98 | // callback(comm::datalayer::DlResult::DL_OK, &_metaData);
99 |
100 | // Take metadata from metadata.mddb
101 | callback(comm::datalayer::DlResult::DL_FAILED, nullptr);
102 | }
103 | };
104 |
105 |
106 | class MinimalSubscriber : public rclcpp::Node
107 | {
108 | comm::datalayer::Variant m_myString;
109 | comm::datalayer::DatalayerSystem m_datalayerSystem;
110 | std::unique_ptr m_provider;
111 | std::unique_ptr m_pippo;
112 | rclcpp::Subscription::SharedPtr m_subscription;
113 |
114 | public:
115 |
116 | MinimalSubscriber()
117 | : Node("minimal_subscriber")
118 | , m_pippo(std::make_unique(MyProviderNode(m_myString)))
119 | {
120 | m_subscription = this->create_subscription(
121 | "ros2_simple_talker_cpp", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
122 |
123 | // Starts the ctrlX Data Layer system without a new broker because one broker is already running on ctrlX CORE
124 | m_datalayerSystem.start(false);
125 | m_provider.reset(getProvider(m_datalayerSystem)); // ctrlX CORE (virtual)
126 | m_pippo->setString("No Message yet");
127 | std::cout << "INFO Register node 'ros/listenercpp/mymessage' " << std::endl;
128 | comm::datalayer::DlResult result = m_provider->registerNode("ros/listenercpp/mymessage",m_pippo.get());
129 | if (STATUS_FAILED(result))
130 | {
131 | std::cout << "WARN Register node 'sdk-cpp-registernode/myString' failed with: " << result.toString() << std::endl;
132 | }
133 | }
134 |
135 | ~MinimalSubscriber()
136 | {
137 | std::cout << __func__ << std::endl;
138 | m_provider->stop();
139 | m_provider = nullptr;
140 | m_datalayerSystem.stop();
141 | }
142 |
143 | private:
144 | void topic_callback(const std_msgs::msg::String & msg) const
145 | {
146 | RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str());
147 | m_pippo->setString( msg.data.c_str() );
148 | }
149 | };
150 |
151 | int main(int argc, char * argv[])
152 | {
153 | rclcpp::init(argc, argv);
154 | {
155 | std::shared_ptr node = std::make_shared();
156 | rclcpp::spin(node);
157 | }
158 | rclcpp::shutdown();
159 | return 0;
160 | }
161 |
--------------------------------------------------------------------------------
/simple-talker-dl-py/src/app/ros2/datalayer_reader_ros2_publisher.py:
--------------------------------------------------------------------------------
1 | """Read the ctrlX Data Layer value and publish it via ROS 2 message."""
2 |
3 | # SPDX-FileCopyrightText: Bosch Rexroth AG
4 | #
5 | # SPDX-License-Identifier: MIT
6 |
7 | import rclpy
8 | from rclpy.node import Node
9 |
10 | import std_msgs.msg
11 |
12 | import ctrlxdatalayer
13 | from ctrlxdatalayer.variant import Result, Variant
14 |
15 | from ctrlx_datalayer.ctrlx_datalayer_helper import get_client
16 |
17 | # Assignment table 'ROS 2 Message Data Type' <-> 'ctrlX Data Layer Variant
18 | # gettter method'.
19 | CTRLX_TO_ROS2_CONVERTERS = {
20 | 'INT8': {
21 | 'ctrlxGetter': Variant.get_int8,
22 | 'msgDataType': std_msgs.msg.Int8},
23 | 'INT16': {
24 | 'ctrlxGetter': Variant.get_int16,
25 | 'msgDataType': std_msgs.msg.Int16},
26 | 'INT32': {
27 | 'ctrlxGetter': Variant.get_int32,
28 | 'msgDataType': std_msgs.msg.Int32},
29 | 'INT64': {
30 | 'ctrlxGetter': Variant.get_int64,
31 | 'msgDataType': std_msgs.msg.Int64},
32 | 'UINT8': {
33 | 'ctrlxGetter': Variant.get_uint8,
34 | 'msgDataType': std_msgs.msg.UInt8},
35 | 'UINT16': {
36 | 'ctrlxGetter': Variant.get_uint16,
37 | 'msgDataType': std_msgs.msg.UInt16},
38 | 'UINT32': {
39 | 'ctrlxGetter': Variant.get_uint32,
40 | 'msgDataType': std_msgs.msg.UInt32},
41 | 'UINT64': {
42 | 'ctrlxGetter': Variant.get_uint64,
43 | 'msgDataType': std_msgs.msg.UInt64},
44 | 'FLOAT32': {
45 | 'ctrlxGetter': Variant.get_float32,
46 | 'msgDataType': std_msgs.msg.Float32},
47 | 'FLOAT64': {
48 | 'ctrlxGetter': Variant.get_float64,
49 | 'msgDataType': std_msgs.msg.Float64},
50 | 'STRING': {
51 | 'ctrlxGetter': Variant.get_string,
52 | 'msgDataType': std_msgs.msg.String},
53 | 'BOOL8': {
54 | 'ctrlxGetter': Variant.get_bool8,
55 | 'msgDataType': std_msgs.msg.Bool},
56 | 'ARRAY_INT8': {
57 | 'ctrlxGetter': Variant.get_array_int8,
58 | 'msgDataType': std_msgs.msg.Int8MultiArray},
59 | 'ARRAY_INT16': {
60 | 'ctrlxGetter': Variant.get_array_int16,
61 | 'msgDataType': std_msgs.msg.Int16MultiArray},
62 | 'ARRAY_INT32': {
63 | 'ctrlxGetter': Variant.get_array_int32,
64 | 'msgDataType': std_msgs.msg.Int32MultiArray},
65 | 'ARRAY_INT64': {
66 | 'ctrlxGetter': Variant.get_array_int64,
67 | 'msgDataType': std_msgs.msg.Int64MultiArray},
68 | 'UInt8MultiArray': {
69 | 'ctrlxGetter': Variant.get_array_uint8,
70 | 'msgDataType': std_msgs.msg.UInt8MultiArray},
71 | 'UInt16MultiArray': {
72 | 'ctrlxGetter': Variant.get_array_uint16,
73 | 'msgDataType': std_msgs.msg.UInt16MultiArray},
74 | 'UInt32MultiArray': {
75 | 'ctrlxGetter': Variant.get_array_uint32,
76 | 'msgDataType': std_msgs.msg.UInt32MultiArray},
77 | 'UInt64MultiArray': {
78 | 'ctrlxGetter': Variant.get_array_uint64,
79 | 'msgDataType': std_msgs.msg.UInt64MultiArray},
80 | 'Float32MultiArray': {
81 | 'ctrlxGetter': Variant.get_array_float32,
82 | 'msgDataType': std_msgs.msg.Float32MultiArray},
83 | 'Float64MultiArray': {
84 | 'ctrlxGetter': Variant.get_array_float64,
85 | 'msgDataType': std_msgs.msg.Float64MultiArray}}
86 |
87 |
88 | class DataLayerReaderRos2Publisher(Node):
89 | """
90 | Class DataLayerReaderRos2Publisher.
91 |
92 | Reads a ctrlX Data Layer varinat value and sends it via ROS 2 message.
93 | """
94 |
95 | def __init__(self, dl_address, ros2_topic):
96 | """
97 | Initialize an instance.
98 |
99 | Constructor of the class.
100 | """
101 | self.dl_address = dl_address
102 | self.ros2_topic = ros2_topic
103 |
104 | self.datalayer_system = None
105 | self.datalayer_client = None
106 | self.getter_method = None
107 | self.ros2_msg_data_type = None
108 | self.ros2_publisher = None
109 | self.timer = None
110 |
111 | def read_data_layer_value(self):
112 | """
113 | Read a ctrlX Data Layer value.
114 |
115 | Returns the value as variant.
116 | """
117 | result, variant = self.datalayer_client.read_sync(self.dl_address)
118 | if result != Result.OK:
119 | print('ERROR Reading ctrlX Data Layer node', self.dl_address, 'failed', result)
120 | return None
121 |
122 | return variant
123 |
124 | def start(self):
125 | """
126 | Start running.
127 |
128 | Connects to the ctrlX Data Layer, initializes the rclpy super class
129 | instance and starts the timer.
130 | """
131 | self.datalayer_system = ctrlxdatalayer.system.System('')
132 | self.datalayer_system.start(False)
133 |
134 | print('INFO Creating ctrlX Data Layer connnection')
135 | self.datalayer_client, connection_string = get_client(self.datalayer_system)
136 | if self.datalayer_client is None:
137 | print('ERROR Creating ctrlX Data Layer connnection to', connection_string, 'failed')
138 | return False
139 |
140 | variant = self.read_data_layer_value()
141 | if variant is None:
142 | return False
143 |
144 | print('INFO Initializing ROS 2 node ctrlxReaderRos2Talker')
145 | super().__init__('ctrlxReaderRos2Talker')
146 |
147 | ctrlx_to_ros2_converter = CTRLX_TO_ROS2_CONVERTERS[variant.get_type().name]
148 | print('INFO ros2_msg', ctrlx_to_ros2_converter)
149 |
150 | self.getter_method = ctrlx_to_ros2_converter['ctrlxGetter']
151 | self.ros2_msg_data_type = ctrlx_to_ros2_converter['msgDataType']
152 | print('INFO Creating ROS 2 publisher: type', self.ros2_msg_data_type, 'topic', self.ros2_topic)
153 | self.ros2_publisher = self.create_publisher(self.ros2_msg_data_type, self.ros2_topic, 10)
154 | if self.ros2_publisher is None:
155 | print('ERROR Creating ROS 2 publisher failed')
156 | return False
157 |
158 | timer_period = 1.0 # seconds
159 | self.timer = self.create_timer(timer_period, self.timer_callback)
160 |
161 | return True
162 |
163 | def timer_callback(self):
164 | """
165 | Handle timer tick.
166 |
167 | Reads a ctrlX Data Layer values and sends it.
168 | """
169 | variant = self.read_data_layer_value()
170 | if variant is None:
171 | return
172 |
173 | ros2_msg = self.ros2_msg_data_type()
174 | ros2_msg.data = self.getter_method(variant)
175 |
176 | with variant:
177 | self.get_logger().info('Publishing "%s"' % ros2_msg.data)
178 | self.ros2_publisher.publish(ros2_msg)
179 |
180 | def stop(self):
181 | """
182 | Stop the app.
183 |
184 | Stops the ctrlX Data Layer and the timer.
185 | """
186 | self.datalayer_system = ctrlxdatalayer.system.System('')
187 | self.datalayer_system.stop(False)
188 |
189 | if self.timer is not None:
190 | self.destroy_timer(self.timer)
191 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ctrlX AUTOMATION Software Development Kit for ROS 2
2 |
3 | This is the Software Development Kit (SDK) to build ROS 2 Applications, that can run on industrial devices that are based on the ctrlX OS platform.
4 |
5 | The **Robot Operating System (ROS)** is an open source robotics software framework that help you build robot applications.
6 | **ctrlX OS** is an industrial grade realtime platform based on Linux which is available for several industrial hardware devices and features an app-based modular architecture that allows you to install additional functionality. This includes apps for industrial fieldbus communication, machine automation, programmable logic control (PLC) and other automation software which can also be found ready-to-run in the [ctrlX Store](https://developer.community.boschrexroth.com/).
7 |
8 | Please note, that this is the first version of the ROS 2 SDK. You may expect more samples and extensions over the course of the next months.
9 |
10 | ## Getting Started
11 |
12 | As a prerequisite you should get yourself familiar with:
13 |
14 | * ROS 2 and its underlying architecture using the official ROS 2 documentation at:
15 | * The [ctrlX AUTOMATION Ecosystem](https://ctrlx-automation.com/) and the architecture of ctrlX OS as well as devices which are capable to run ctrlX OS. E.g. ctrlX CORE devices from [Bosch Rexroth](https://www.boschrexroth.com/).
16 | * The [ctrlX AUTOMATION SDK](https://github.com/boschrexroth/ctrlx-automation-sdk) which is the underlying SDK that allows you to create any kind of App for ctrlX OS and is the foundation for the ctrlX AUTOMATION Software Development Kit for ROS 2. [Link to SDK Documentation](https://boschrexroth.github.io/ctrlx-automation-sdk/)
17 |
18 | ## Usage
19 |
20 | This SDK builds on top of the [ctrlX AUTOMATION SDK](https://github.com/boschrexroth/ctrlx-automation-sdk) to make apps for ctrlX OS, which is itself based on Ubuntu Core Distribution and a Linux kernel with PREEMPT_RT patch.
21 |
22 | ctrlX OS, Ubuntu Core, as well as ROS 2 are released as *distributions*. This release of the SDK is intended to be used with:
23 |
24 | * ctrlX OS 2.x (Includes Ubuntu Core 22)
25 | * ROS 2 [Humble Hawksbill](https://docs.ros.org/en/humble/)
26 |
27 | All projects use [Visual Studio Code](https://code.visualstudio.com/) as editor.
28 |
29 | ### ROS 2 Humble Base Snap
30 |
31 | To build and deploy a ROS 2 application to ctrlX OS it needs to be package as [snap](https://ubuntu.com/core/services/guide/snaps-intro). In order to make your development process as efficient as possible we recommend splitting your ROS 2 deployment into at least two snaps. A so-called *base snap* is used to encapsulate the ROS 2 runtime as well as libraries which are dependencies to your application. The *base snap* is installed on ctrlX OS once and provides the compiled runtime and libraries to one or more ROS 2 application snaps which hold your business logic. Following this approach you can reduce build times and resource footprint on the device by sharing the ROS 2 dependencies.
32 |
33 | For details have a look at the instructions for the [ROS 2 Humble Base Snap](ros2-base-humble-deb/README.md) which also shows you how to compile ROS 2 for ctrlX OS.
34 |
35 | If you nevertheless want to go with a single app, then use the *base snap* and integrate your ROS 2 application directly.
36 |
37 | ## Samples
38 |
39 | This SDK contains also multiple project examples to show the usage of ROS 2. All examples build on top of the *base snap*.
40 |
41 | ### ROS 2 Humble Applications in C++
42 |
43 | #### Learn how to package your application as snap
44 |
45 | This example is based on the official ROS 2 Tutorial and adjusted to run on ctrlX OS together with the *base snap*. You can find the original source code at [ROS 2 Humble Tutorials - Writing a simple publisher and subscriber (C++)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html#writing-a-simple-publisher-and-subscriber-c)
46 |
47 | * [`simple-talker-cpp/`](simple-talker-cpp/README.md) contains the snap version of the described publisher (talker)
48 | * [`simple-listener-cpp/`](simple-listener-cpp/README.md) contains the snap version of the described subscriber (listener)
49 |
50 | #### Learn how to access the ctrlX Data Layer from your application
51 |
52 | the ctrlX Data Layer is the realtime message broker that runs on ctrlX OS. It is used by all ctrlX Apps to publish and exchange variables, types, methods and programs. In the ctrlX Data Layer you can find all device, process, fieldbus and periphery data. You can connect to the ctrlX Data Layer via TCP/IP or IPC.
53 |
54 | * [`simple-talker-dl-cpp/`](simple-talker-dl-cpp/README.md) read from ctrlX Data Layer and publish as ROS message (talker)
55 | * [`simple-listener-dl-cpp/`](simple-listener-dl-cpp/README.md) subscribe to ROS message and publish in ctrlX Data Layer (listener)
56 |
57 | ### ROS 2 Humble Applications in Python
58 |
59 | #### Writing a Simple Publisher and Subscriber (Python)
60 |
61 | This example is based on the official ROS 2 Tutorial and adjusted to run on ctrlX OS together with the *base snap*. You can find the original source code at [ROS 2 Humble Tutorials - Writing a simple publisher and subscriber (Python)](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Py-Publisher-And-Subscriber.html)
62 |
63 | * [`simple-talker-py/`](simple-talker-py/README.md) contains the snap version of the described publisher (talker)
64 | * [`simple-listener-py/`](simple-listener-py/README.md) contains the snap version of the described subscriber (listener)
65 |
66 | #### Writing a Simple Publisher and Subscriber with ctrlX Data Layer Access (Python)
67 |
68 | Both sample projects are based on the same official ROS 2 tutorial as mentioned above. Additionally, the example is extended with access to the ctrlX Data Layer using the ctrlX SDK.
69 |
70 | * [`simple-talker-dl-py/`](simple-talker-dl-py/README.md) Reads a Data Layer value and publishes it as ROS 2 message under a specific topic.
71 | * [`simple-listener-dl-py/`](simple-listener-dl-py/README.md) Subscribes messages of the topic, receives the value and writes it into the ctrlX Data Layer.
72 |
73 | ## Support
74 |
75 | This repository is provided and maintained by [Bosch Rexroth](https://www.boschrexroth.com). Feel free to check out and be part of the [ctrlX AUTOMATION Community](https://ctrlx-automation.com/community). Get additional support, e.g. related to Bosch Rexroth Devices, Apps, SDKs and Services, or leave some ideas and feedback.
76 |
77 | To report bugs, request changes and discuss new ideas you may also have a look at the issue tracker of this repository:
78 |
79 |
80 | ## Important directions for use
81 |
82 | ### Areas of use and application
83 |
84 | The content (e.g. source code and related documents) of this repository is intended to be used for configuration, parameterization, programming or diagnostics in combination with selected Bosch Rexroth ctrlX AUTOMATION devices.
85 | Additionally, the specifications given in the "Areas of Use and Application" for ctrlX AUTOMATION devices used with the content of this repository do also apply.
86 |
87 | ### Unintended use
88 |
89 | Any use of the source code and related documents of this repository in applications other than those specified above or under operating conditions other than those described in the documentation and the technical specifications is considered as "unintended". Furthermore, this software must not be used in any application areas not expressly approved by Bosch Rexroth.
90 |
91 | ## Changelog
92 |
93 | ```text
94 | * 2025-01-16: 2.4.0 - update to snapcraft version 7.x
95 | * 2024-12-06: 2.3.0 - update and fixed runtime environment
96 | * 2024-12-05: 2.2.0 - Merge with https://github.com/boschrexroth/ctrlx-automation-sdk-ros2
97 | * 2024-06-28: 2.0.1 - Improve documentation, use symbolic links for build scripts
98 | * 2023-09-01: 2.0.0 - Initial release for ROS 2 Humble Hawksbill.
99 | ```
100 |
101 | ## About
102 |
103 | SPDX-FileCopyrightText: Copyright (c) 2025 Bosch Rexroth AG
104 |
105 |
106 |
107 | ## Licenses
108 |
109 | SPDX-License-Identifier: MIT
110 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/go,c++,linux,csharp,windows,snapcraft,macos
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=go,c++,linux,csharp,windows,snapcraft,macos
4 |
5 | ### C++ ###
6 | # Prerequisites
7 | *.d
8 |
9 | # Compiled Object files
10 | *.slo
11 | *.lo
12 | *.o
13 | *.obj
14 |
15 | # Precompiled Headers
16 | *.gch
17 | *.pch
18 |
19 | # Linker files
20 | *.ilk
21 |
22 | # Debugger Files
23 | *.pdb
24 |
25 | # Compiled Dynamic libraries
26 | *.so
27 | *.dylib
28 | *.dll
29 |
30 | # Fortran module files
31 | *.mod
32 | *.smod
33 |
34 | # Compiled Static libraries
35 | *.lai
36 | *.la
37 | *.a
38 | *.lib
39 |
40 | # Executables
41 | *.exe
42 | *.out
43 | *.app
44 |
45 | ### Csharp ###
46 | ## Ignore Visual Studio temporary files, build results, and
47 | ## files generated by popular Visual Studio add-ons.
48 | ##
49 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
50 |
51 | # User-specific files
52 | *.rsuser
53 | *.suo
54 | *.user
55 | *.userosscache
56 | *.sln.docstates
57 |
58 | # User-specific files (MonoDevelop/Xamarin Studio)
59 | *.userprefs
60 |
61 | # Mono auto generated files
62 | mono_crash.*
63 |
64 | # Build results
65 | [Dd]ebug/
66 | [Dd]ebugPublic/
67 | [Rr]elease/
68 | [Rr]eleases/
69 | x64/
70 | x86/
71 | [Ww][Ii][Nn]32/
72 | [Aa][Rr][Mm]/
73 | [Aa][Rr][Mm]64/
74 | bld/
75 | [Bb]in/
76 | [Oo]bj/
77 | [Ll]og/
78 | [Ll]ogs/
79 |
80 | # Visual Studio 2015/2017 cache/options directory
81 | .vs/
82 | # Uncomment if you have tasks that create the project's static files in wwwroot
83 | #wwwroot/
84 |
85 | # Visual Studio 2017 auto generated files
86 | Generated\ Files/
87 |
88 | # MSTest test Results
89 | [Tt]est[Rr]esult*/
90 | [Bb]uild[Ll]og.*
91 |
92 | # NUnit
93 | *.VisualState.xml
94 | TestResult.xml
95 | nunit-*.xml
96 |
97 | # Build Results of an ATL Project
98 | [Dd]ebugPS/
99 | [Rr]eleasePS/
100 | dlldata.c
101 |
102 | # Benchmark Results
103 | BenchmarkDotNet.Artifacts/
104 |
105 | # .NET Core
106 | project.lock.json
107 | project.fragment.lock.json
108 | artifacts/
109 |
110 | # ASP.NET Scaffolding
111 | ScaffoldingReadMe.txt
112 |
113 | # StyleCop
114 | StyleCopReport.xml
115 |
116 | # Files built by Visual Studio
117 | *_i.c
118 | *_p.c
119 | *_h.h
120 | *.meta
121 | *.iobj
122 | *.ipdb
123 | *.pgc
124 | *.pgd
125 | *.rsp
126 | *.sbr
127 | *.tlb
128 | *.tli
129 | *.tlh
130 | *.tmp
131 | *.tmp_proj
132 | *_wpftmp.csproj
133 | *.log
134 | *.vspscc
135 | *.vssscc
136 | .builds
137 | *.pidb
138 | *.svclog
139 | *.scc
140 |
141 | # Chutzpah Test files
142 | _Chutzpah*
143 |
144 | # Visual C++ cache files
145 | ipch/
146 | *.aps
147 | *.ncb
148 | *.opendb
149 | *.opensdf
150 | *.sdf
151 | *.cachefile
152 | *.VC.db
153 | *.VC.VC.opendb
154 |
155 | # Visual Studio profiler
156 | *.psess
157 | *.vsp
158 | *.vspx
159 | *.sap
160 |
161 | # Visual Studio Trace Files
162 | *.e2e
163 |
164 | # TFS 2012 Local Workspace
165 | $tf/
166 |
167 | # Guidance Automation Toolkit
168 | *.gpState
169 |
170 | # ReSharper is a .NET coding add-in
171 | _ReSharper*/
172 | *.[Rr]e[Ss]harper
173 | *.DotSettings.user
174 |
175 | # TeamCity is a build add-in
176 | _TeamCity*
177 |
178 | # DotCover is a Code Coverage Tool
179 | *.dotCover
180 |
181 | # AxoCover is a Code Coverage Tool
182 | .axoCover/*
183 | !.axoCover/settings.json
184 |
185 | # Coverlet is a free, cross platform Code Coverage Tool
186 | coverage*.[ji][sn][of][no]
187 | coverage*.xml
188 |
189 | # Visual Studio code coverage results
190 | *.coverage
191 | *.coveragexml
192 |
193 | # NCrunch
194 | _NCrunch_*
195 | .*crunch*.local.xml
196 | nCrunchTemp_*
197 |
198 | # MightyMoose
199 | *.mm.*
200 | AutoTest.Net/
201 |
202 | # Web workbench (sass)
203 | .sass-cache/
204 |
205 | # Installshield output folder
206 | [Ee]xpress/
207 |
208 | # DocProject is a documentation generator add-in
209 | DocProject/buildhelp/
210 | DocProject/Help/*.HxT
211 | DocProject/Help/*.HxC
212 | DocProject/Help/*.hhc
213 | DocProject/Help/*.hhk
214 | DocProject/Help/*.hhp
215 | DocProject/Help/Html2
216 | DocProject/Help/html
217 |
218 | # Click-Once directory
219 | publish/
220 |
221 | # Publish Web Output
222 | *.[Pp]ublish.xml
223 | *.azurePubxml
224 | # Note: Comment the next line if you want to checkin your web deploy settings,
225 | # but database connection strings (with potential passwords) will be unencrypted
226 | *.pubxml
227 | *.publishproj
228 |
229 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
230 | # checkin your Azure Web App publish settings, but sensitive information contained
231 | # in these scripts will be unencrypted
232 | PublishScripts/
233 |
234 | # NuGet Packages
235 | *.nupkg
236 | # NuGet Symbol Packages
237 | *.snupkg
238 | # The packages folder can be ignored because of Package Restore
239 | **/[Pp]ackages/*
240 | # except build/, which is used as an MSBuild target.
241 | !**/[Pp]ackages/build/
242 | # Uncomment if necessary however generally it will be regenerated when needed
243 | #!**/[Pp]ackages/repositories.config
244 | # NuGet v3's project.json files produces more ignorable files
245 | *.nuget.props
246 | *.nuget.targets
247 |
248 | # Microsoft Azure Build Output
249 | csx/
250 | *.build.csdef
251 |
252 | # Microsoft Azure Emulator
253 | ecf/
254 | rcf/
255 |
256 | # Windows Store app package directories and files
257 | AppPackages/
258 | BundleArtifacts/
259 | Package.StoreAssociation.xml
260 | _pkginfo.txt
261 | *.appx
262 | *.appxbundle
263 | *.appxupload
264 |
265 | # Visual Studio cache files
266 | # files ending in .cache can be ignored
267 | *.[Cc]ache
268 | # but keep track of directories ending in .cache
269 | !?*.[Cc]ache/
270 |
271 | # Others
272 | ClientBin/
273 | ~$*
274 | *~
275 | *.dbmdl
276 | *.dbproj.schemaview
277 | *.jfm
278 | *.pfx
279 | *.publishsettings
280 | orleans.codegen.cs
281 |
282 | # Including strong name files can present a security risk
283 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
284 | #*.snk
285 |
286 | # Since there are multiple workflows, uncomment next line to ignore bower_components
287 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
288 | #bower_components/
289 |
290 | # RIA/Silverlight projects
291 | Generated_Code/
292 |
293 | # Backup & report files from converting an old project file
294 | # to a newer Visual Studio version. Backup files are not needed,
295 | # because we have git ;-)
296 | _UpgradeReport_Files/
297 | Backup*/
298 | UpgradeLog*.XML
299 | UpgradeLog*.htm
300 | ServiceFabricBackup/
301 | *.rptproj.bak
302 |
303 | # SQL Server files
304 | *.mdf
305 | *.ldf
306 | *.ndf
307 |
308 | # Business Intelligence projects
309 | *.rdl.data
310 | *.bim.layout
311 | *.bim_*.settings
312 | *.rptproj.rsuser
313 | *- [Bb]ackup.rdl
314 | *- [Bb]ackup ([0-9]).rdl
315 | *- [Bb]ackup ([0-9][0-9]).rdl
316 |
317 | # Microsoft Fakes
318 | FakesAssemblies/
319 |
320 | # GhostDoc plugin setting file
321 | *.GhostDoc.xml
322 |
323 | # Node.js Tools for Visual Studio
324 | .ntvs_analysis.dat
325 | node_modules/
326 |
327 | # Visual Studio 6 build log
328 | *.plg
329 |
330 | # Visual Studio 6 workspace options file
331 | *.opt
332 |
333 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
334 | *.vbw
335 |
336 | # Visual Studio LightSwitch build output
337 | **/*.HTMLClient/GeneratedArtifacts
338 | **/*.DesktopClient/GeneratedArtifacts
339 | **/*.DesktopClient/ModelManifest.xml
340 | **/*.Server/GeneratedArtifacts
341 | **/*.Server/ModelManifest.xml
342 | _Pvt_Extensions
343 |
344 | # Paket dependency manager
345 | .paket/paket.exe
346 | paket-files/
347 |
348 | # FAKE - F# Make
349 | .fake/
350 |
351 | # CodeRush personal settings
352 | .cr/personal
353 |
354 | # Python Tools for Visual Studio (PTVS)
355 | __pycache__/
356 | *.pyc
357 |
358 | # Cake - Uncomment if you are using it
359 | # tools/**
360 | # !tools/packages.config
361 |
362 | # Tabs Studio
363 | *.tss
364 |
365 | # Telerik's JustMock configuration file
366 | *.jmconfig
367 |
368 | # BizTalk build output
369 | *.btp.cs
370 | *.btm.cs
371 | *.odx.cs
372 | *.xsd.cs
373 |
374 | # OpenCover UI analysis results
375 | OpenCover/
376 |
377 | # Azure Stream Analytics local run output
378 | ASALocalRun/
379 |
380 | # MSBuild Binary and Structured Log
381 | *.binlog
382 |
383 | # NVidia Nsight GPU debugger configuration file
384 | *.nvuser
385 |
386 | # MFractors (Xamarin productivity tool) working folder
387 | .mfractor/
388 |
389 | # Local History for Visual Studio
390 | .localhistory/
391 |
392 | # BeatPulse healthcheck temp database
393 | healthchecksdb
394 |
395 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
396 | MigrationBackup/
397 |
398 | # Ionide (cross platform F# VS Code tools) working folder
399 | .ionide/
400 |
401 | # Fody - auto-generated XML schema
402 | FodyWeavers.xsd
403 |
404 | ### Go ###
405 | # Binaries for programs and plugins
406 | *.exe~
407 |
408 | # Test binary, built with `go test -c`
409 | *.test
410 |
411 | # Output of the go coverage tool, specifically when used with LiteIDE
412 |
413 | # Dependency directories (remove the comment below to include it)
414 | # vendor/
415 |
416 | ### Go Patch ###
417 | /vendor/
418 | /Godeps/
419 |
420 | ### Linux ###
421 |
422 | # temporary files which can be created if a process still has a handle open of a deleted file
423 | .fuse_hidden*
424 |
425 | # KDE directory preferences
426 | .directory
427 |
428 | # Linux trash folder which might appear on any partition or disk
429 | .Trash-*
430 |
431 | # .nfs files are created when an open file is removed but is still being accessed
432 | .nfs*
433 |
434 | ### macOS ###
435 | # General
436 | .DS_Store
437 | .AppleDouble
438 | .LSOverride
439 |
440 | # Icon must end with two \r
441 | Icon
442 |
443 |
444 | # Thumbnails
445 | ._*
446 |
447 | # Files that might appear in the root of a volume
448 | .DocumentRevisions-V100
449 | .fseventsd
450 | .Spotlight-V100
451 | .TemporaryItems
452 | .Trashes
453 | .VolumeIcon.icns
454 | .com.apple.timemachine.donotpresent
455 |
456 | # Directories potentially created on remote AFP share
457 | .AppleDB
458 | .AppleDesktop
459 | Network Trash Folder
460 | Temporary Items
461 | .apdisk
462 |
463 | ### Snapcraft ###
464 | /parts/
465 | /stage/
466 | /prime/
467 | *.snap
468 | /deb
469 |
470 | # Snapcraft global state tracking data(automatically generated)
471 | # https://forum.snapcraft.io/t/location-to-save-global-state/768
472 | /snap/.snapcraft/
473 |
474 | # Source archive packed by `snapcraft cleanbuild` before pushing to the LXD container
475 | /*_source.tar.bz2
476 |
477 | ### Windows ###
478 | # Windows thumbnail cache files
479 | Thumbs.db
480 | Thumbs.db:encryptable
481 | ehthumbs.db
482 | ehthumbs_vista.db
483 |
484 | # Dump file
485 | *.stackdump
486 |
487 | # Folder config file
488 | [Dd]esktop.ini
489 |
490 | # Recycle Bin used on file shares
491 | $RECYCLE.BIN/
492 |
493 | # Windows Installer files
494 | *.cab
495 | *.msi
496 | *.msix
497 | *.msm
498 | *.msp
499 |
500 | # Windows shortcuts
501 | *.lnk
502 |
503 | # End of https://www.toptal.com/developers/gitignore/api/go,c++,linux,csharp,windows,snapcraft,macos
504 |
--------------------------------------------------------------------------------
/LICENSES/Apache-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------