(
51 | name, value, on_change_callback, this->get_node_parameters_interface(), true);
52 | }
53 |
54 | protected:
55 | rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr ParamCallback() const;
56 |
57 | private:
58 | ParameterHandler param_handler_;
59 | rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr param_callback_;
60 | };
61 | } // namespace kuka_drivers_core
62 |
63 | #endif // KUKA_DRIVERS_CORE__ROS2_BASE_NODE_HPP_
64 |
--------------------------------------------------------------------------------
/controllers/fri_configuration_controller/include/fri_configuration_controller/visibility_control.h:
--------------------------------------------------------------------------------
1 | // Copyright 2023 KUKA Hungaria Kft.
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 | #ifndef FRI_CONFIGURATION_CONTROLLER__VISIBILITY_CONTROL_H_
16 | #define FRI_CONFIGURATION_CONTROLLER__VISIBILITY_CONTROL_H_
17 |
18 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki:
19 | // https://gcc.gnu.org/wiki/Visibility
20 |
21 | #if defined _WIN32 || defined __CYGWIN__
22 | #ifdef __GNUC__
23 | #define FRI_CONFIGURATION_CONTROLLER_EXPORT __attribute__((dllexport))
24 | #define FRI_CONFIGURATION_CONTROLLER_IMPORT __attribute__((dllimport))
25 | #else
26 | #define FRI_CONFIGURATION_CONTROLLER_EXPORT __declspec(dllexport)
27 | #define FRI_CONFIGURATION_CONTROLLER_IMPORT __declspec(dllimport)
28 | #endif
29 | #ifdef FRI_CONFIGURATION_CONTROLLER_BUILDING_LIBRARY
30 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC FRI_CONFIGURATION_CONTROLLER_EXPORT
31 | #else
32 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC FRI_CONFIGURATION_CONTROLLER_IMPORT
33 | #endif
34 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC_TYPE FRI_CONFIGURATION_CONTROLLER_PUBLIC
35 | #define FRI_CONFIGURATION_CONTROLLER_LOCAL
36 | #else
37 | #define FRI_CONFIGURATION_CONTROLLER_EXPORT __attribute__((visibility("default")))
38 | #define FRI_CONFIGURATION_CONTROLLER_IMPORT
39 | #if __GNUC__ >= 4
40 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC __attribute__((visibility("default")))
41 | #define FRI_CONFIGURATION_CONTROLLER_LOCAL __attribute__((visibility("hidden")))
42 | #else
43 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC
44 | #define FRI_CONFIGURATION_CONTROLLER_LOCAL
45 | #endif
46 | #define FRI_CONFIGURATION_CONTROLLER_PUBLIC_TYPE
47 | #endif
48 |
49 | #endif // FRI_CONFIGURATION_CONTROLLER__VISIBILITY_CONTROL_H_
50 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/config/gpio_config.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 0
7 |
8 |
9 | 0
10 |
11 |
12 | 0
13 |
14 |
15 | 0
16 |
17 |
18 | 0
19 |
20 |
21 | 0
22 |
23 |
24 | 0
25 |
26 |
27 | 0
28 |
29 |
30 | 0
31 |
32 |
33 | 0
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/kuka_iiqka_eac_driver/test/test_driver_startup.py:
--------------------------------------------------------------------------------
1 | # Copyright 2024 KUKA Hungaria Kft.
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 | import unittest
16 |
17 | import launch
18 | import launch.actions
19 | import launch_testing.actions
20 | import launch_testing.markers
21 | import pytest
22 |
23 | from launch.launch_description_sources.python_launch_description_source import (
24 | PythonLaunchDescriptionSource,
25 | )
26 | from launch.actions.include_launch_description import IncludeLaunchDescription
27 | from ament_index_python.packages import get_package_share_directory
28 |
29 |
30 | # Launch driver startup
31 | @pytest.mark.launch_test
32 | @launch_testing.markers.keep_alive
33 | def generate_test_description():
34 | return launch.LaunchDescription(
35 | [
36 | IncludeLaunchDescription(
37 | PythonLaunchDescriptionSource(
38 | [
39 | get_package_share_directory("kuka_iiqka_eac_driver"),
40 | "/launch/",
41 | "startup.launch.py",
42 | ]
43 | ),
44 | launch_arguments={
45 | "cm_log_level": "INFO",
46 | }.items(),
47 | ),
48 | launch_testing.actions.ReadyToTest(),
49 | ]
50 | )
51 |
52 |
53 | class TestDriverStartup(unittest.TestCase):
54 | def test_read_stdout(self, proc_output):
55 | # Check for successful initialization
56 | proc_output.assertWaitFor("Robot initialized", timeout=5)
57 | proc_output.assertWaitFor(
58 | "Successful initialization of hardware 'lbr_iisy3_r760'", timeout=5
59 | )
60 | # Check whether disabling automatic activation was successful
61 | proc_output.assertWaitFor(
62 | "Setting component 'lbr_iisy3_r760' to 'unconfigured' state.", timeout=5
63 | )
64 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/robot_application/src/application/ROS2_Control.java:
--------------------------------------------------------------------------------
1 | package application;
2 |
3 | import javax.inject.Inject;
4 |
5 | import ros2.modules.FRIManager;
6 | import ros2.modules.ROS2Connection;
7 | import ros2.modules.TCPConnection;
8 |
9 | import com.kuka.roboticsAPI.applicationModel.RoboticsAPIApplication;
10 | import com.kuka.roboticsAPI.deviceModel.LBR;
11 |
12 | /**
13 | * Implementation of a robot application.
14 | *
15 | * The application provides a {@link RoboticsAPITask#initialize()} and a
16 | * {@link RoboticsAPITask#run()} method, which will be called successively in
17 | * the application lifecycle. The application will terminate automatically after
18 | * the {@link RoboticsAPITask#run()} method has finished or after stopping the
19 | * task. The {@link RoboticsAPITask#dispose()} method will be called, even if an
20 | * exception is thrown during initialization or run.
21 | *
22 | * It is imperative to call super.dispose() when overriding the
23 | * {@link RoboticsAPITask#dispose()} method.
24 | *
25 | * @see UseRoboticsAPIContext
26 | * @see #initialize()
27 | * @see #run()
28 | * @see #dispose()
29 | */
30 | public class ROS2_Control extends RoboticsAPIApplication {
31 | @Inject
32 | private LBR _lbr;
33 |
34 | private TCPConnection _TCPConnection;
35 | private ROS2Connection _ROS2Connection;
36 | private FRIManager _FRIManager;
37 |
38 | @Override
39 | public void initialize() {
40 | // initialize your application here
41 | _TCPConnection = new TCPConnection(30000);
42 | _ROS2Connection = new ROS2Connection();
43 | _FRIManager = new FRIManager(_lbr, getApplicationControl());
44 |
45 | _FRIManager.registerROS2ConnectionModule(_ROS2Connection);
46 | _TCPConnection.registerROS2ConnectionModule(_ROS2Connection);
47 | _ROS2Connection.registerTCPConnectionModule(_TCPConnection);
48 | _ROS2Connection.registerFRIManagerModule(_FRIManager);
49 | }
50 |
51 | @Override
52 | public void run() {
53 | // your application execution starts here
54 | _ROS2Connection.acceptCommands();
55 | _TCPConnection.openConnection();
56 | _TCPConnection.waitUntilDisconnected();
57 | _ROS2Connection.rejectCommands();
58 | _FRIManager.close();
59 | }
60 |
61 | @Override
62 | public void dispose() {
63 | getLogger().info("disposes");
64 | _TCPConnection.closeConnection();
65 | _FRIManager.close();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/controllers/joint_group_impedance_controller/include/joint_group_impedance_controller/visibility_control.h:
--------------------------------------------------------------------------------
1 | // Copyright 2023 KUKA Hungaria Kft.
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 | #ifndef JOINT_GROUP_IMPEDANCE_CONTROLLER__VISIBILITY_CONTROL_H_
16 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER__VISIBILITY_CONTROL_H_
17 |
18 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki:
19 | // https://gcc.gnu.org/wiki/Visibility
20 |
21 | #if defined _WIN32 || defined __CYGWIN__
22 | #ifdef __GNUC__
23 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_EXPORT __attribute__((dllexport))
24 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_IMPORT __attribute__((dllimport))
25 | #else
26 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_EXPORT __declspec(dllexport)
27 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_IMPORT __declspec(dllimport)
28 | #endif
29 | #ifdef JOINT_GROUP_IMPEDANCE_CONTROLLER_BUILDING_LIBRARY
30 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC JOINT_GROUP_IMPEDANCE_CONTROLLER_EXPORT
31 | #else
32 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC JOINT_GROUP_IMPEDANCE_CONTROLLER_IMPORT
33 | #endif
34 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC_TYPE JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC
35 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_LOCAL
36 | #else
37 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_EXPORT __attribute__((visibility("default")))
38 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_IMPORT
39 | #if __GNUC__ >= 4
40 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC __attribute__((visibility("default")))
41 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_LOCAL __attribute__((visibility("hidden")))
42 | #else
43 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC
44 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_LOCAL
45 | #endif
46 | #define JOINT_GROUP_IMPEDANCE_CONTROLLER_PUBLIC_TYPE
47 | #endif
48 |
49 | #endif // JOINT_GROUP_IMPEDANCE_CONTROLLER__VISIBILITY_CONTROL_H_
50 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/robot_application/src/ros2/serialization/FRIConfigurationParams.java:
--------------------------------------------------------------------------------
1 | package ros2.serialization;
2 |
3 | import java.io.Externalizable;
4 | import java.io.IOException;
5 | import java.io.ObjectInput;
6 | import java.io.ObjectOutput;
7 | import com.kuka.connectivity.fastRobotInterface.FRIConfiguration;
8 | import com.kuka.roboticsAPI.deviceModel.Device;
9 |
10 | public class FRIConfigurationParams implements Externalizable {
11 |
12 | public static final int length = 16; // 4 integers
13 |
14 |
15 | private String _remoteIP;
16 | private int _remotePort;
17 | private int _sendPeriodMilliSec;
18 | private int _receiveMultiplier;
19 |
20 | @Override
21 | public void writeExternal(ObjectOutput out) throws IOException {
22 | out.writeBytes(_remoteIP);
23 | out.writeInt(_remotePort);
24 | out.writeInt(_sendPeriodMilliSec);
25 | out.writeInt(_receiveMultiplier);
26 | }
27 |
28 | @Override
29 | public void readExternal(ObjectInput in) throws IOException,
30 | ClassNotFoundException {
31 | _remotePort = in.readInt();
32 | _sendPeriodMilliSec = in.readInt();
33 | _receiveMultiplier = in.readInt();
34 | _remoteIP = "192.168.38.6";
35 |
36 | int ip = in.readInt();
37 | _remoteIP = String.format("%d.%d.%d.%d", (ip & 0xff),(ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
38 |
39 | System.out.println("FRI configuration: client IP: " + _remoteIP + ":" + _remotePort + ", send_period [ms]: " + _sendPeriodMilliSec + ", receive multiplier: " + _receiveMultiplier);
40 | }
41 |
42 | public FRIConfigurationParams() {
43 | _remoteIP = "0.0.0.0";
44 | _remotePort = 30200;
45 | _sendPeriodMilliSec = 10;
46 | _receiveMultiplier = 1;
47 | }
48 |
49 | public FRIConfigurationParams(FRIConfiguration friConfiguration){
50 | _remoteIP = friConfiguration.getHostName();
51 | _remotePort = friConfiguration.getPortOnRemote();
52 | _sendPeriodMilliSec = friConfiguration.getSendPeriodMilliSec();
53 | _receiveMultiplier = friConfiguration.getReceiveMultiplier();
54 | }
55 |
56 | public FRIConfiguration toFRIConfiguration(Device device){
57 | FRIConfiguration friConfiguration = FRIConfiguration.createRemoteConfiguration(device, _remoteIP);
58 | friConfiguration.setPortOnRemote(_remotePort);
59 | friConfiguration.setSendPeriodMilliSec(_sendPeriodMilliSec);
60 | friConfiguration.setReceiveMultiplier(_receiveMultiplier);
61 | return friConfiguration;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/examples/iiqka_moveit_example/src/moveit_collision_avoidance_example.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Áron Svastits
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 "iiqka_moveit_example/moveit_example.hpp"
19 |
20 | int main(int argc, char * argv[])
21 | {
22 | // Setup
23 | // Initialize ROS and create the Node
24 | rclcpp::init(argc, argv);
25 | auto const example_node = std::make_shared();
26 | rclcpp::executors::SingleThreadedExecutor executor;
27 | executor.add_node(example_node);
28 | std::thread([&executor]() { executor.spin(); }).detach();
29 |
30 | example_node->initialize();
31 |
32 | // Add robot platform
33 | example_node->addRobotPlatform();
34 |
35 | // Go to correct position for the example
36 | auto init_trajectory = example_node->planToPosition(
37 | std::vector{0.3587, 0.3055, -1.3867, 0.0, -0.4896, -0.3587});
38 | if (init_trajectory != nullptr)
39 | {
40 | example_node->moveGroupInterface()->execute(*init_trajectory);
41 | }
42 |
43 | // Add collision object
44 | example_node->addCollisionBox(
45 | geometry_msgs::build().x(0.125).y(0.15).z(0.5),
46 | geometry_msgs::build().x(0.1).y(1.0).z(0.1));
47 | example_node->addBreakPoint();
48 |
49 | auto standing_pose =
50 | Eigen::Isometry3d(Eigen::Translation3d(0.1, 0, 0.8) * Eigen::Quaterniond::Identity());
51 |
52 | // Plan with collision avoidance
53 | auto planned_trajectory =
54 | example_node->planToPoint(standing_pose, "ompl", "RRTConnectkConfigDefault");
55 | if (planned_trajectory != nullptr)
56 | {
57 | example_node->drawTrajectory(*planned_trajectory);
58 | example_node->addBreakPoint();
59 | example_node->moveGroupInterface()->execute(*planned_trajectory);
60 | }
61 |
62 | // Shutdown ROS
63 | rclcpp::shutdown();
64 | return 0;
65 | }
66 |
--------------------------------------------------------------------------------
/.github/workflows/industrial_ci_humble.yml:
--------------------------------------------------------------------------------
1 | name: ROS-Industrial CI humble
2 | run-name: ROS-Industrial CI - ${{ github.event_name }}
3 |
4 | # This determines when this workflow is run
5 | # on: [push, pull_request] # on all pushes and PRs
6 |
7 | # or more fine-grained
8 | on:
9 | push:
10 | branches:
11 | - humble
12 | paths-ignore:
13 | - doc/**
14 | - '**.md'
15 | - LICENSE
16 | - .github/workflows/deploy_wiki.yml
17 | pull_request:
18 | branches:
19 | - humble
20 |
21 | schedule:
22 | # Run every Monday at 1PM UTC
23 | - cron: 0 13 * * 1
24 |
25 | jobs:
26 | industrial_ci:
27 | name: ROS-Industrial CI humble
28 | env:
29 | ROS_REPO: ros
30 | BUILDER: colcon
31 | ANALYZER: sonarqube
32 | TEST_COVERAGE: true
33 | UPSTREAM_WORKSPACE: 'github:kroshu/kuka_robot_descriptions#humble github:kroshu/kuka-external-control-sdk#master'
34 | ROS_DISTRO: humble
35 | CCACHE_DIR: /github/home/.ccache # Directory for ccache (and how we enable ccache in industrial_ci)
36 | EVENT_NAME: ${{ github.event_name }}
37 | BRANCH: ${{ github.event.ref }}
38 | PR_BRANCH: ${{ github.event.pull_request.head.ref }}
39 | PR_BASE: ${{ github.event.pull_request.base.ref }}
40 | PR_NUMBER: ${{ github.event.number }}
41 | ANALYZER_TOKEN: ${{ secrets.ANALYZER_TOKEN }}
42 | DEBUG_BASH: true
43 | runs-on: ubuntu-latest
44 | steps:
45 | - name: Reset ANALYZER for scheduled and push runs
46 | run: |
47 | if [[ "${{ github.event_name }}" == "schedule" ]] || { [[ "${{ github.event_name }}" == "push" ]] && [[ "${{ github.ref }}" != "refs/heads/humble" ]]; }; then
48 | echo "ANALYZER=" >> $GITHUB_ENV
49 | fi
50 | - name: Checkout code
51 | if: github.event.schedule != ''
52 | uses: actions/checkout@v2
53 | with:
54 | fetch-depth: 0
55 | ref: humble
56 | - name: Checkout humble branch for scheduled runs
57 | if: github.event.schedule == ''
58 | uses: actions/checkout@v2
59 | with:
60 | fetch-depth: 0
61 |
62 | # This step will fetch/store the directory used by ccache before/after the ci run
63 | - uses: actions/cache@v4
64 | with:
65 | path: ${{ env.CCACHE_DIR }}
66 | key: ccache-${{ matrix.env.ROS_DISTRO }}-${{ matrix.env.ROS_REPO }}
67 |
68 | # Run industrial_ci
69 | - uses: 'kroshu/industrial_ci@master'
70 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/test/test_driver_startup.py:
--------------------------------------------------------------------------------
1 | # Copyright 2024 KUKA Hungaria Kft.
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 | import unittest
16 |
17 | import launch
18 | import launch.actions
19 | import launch_testing.actions
20 | import launch_testing.markers
21 | import pytest
22 |
23 | from launch.launch_description_sources.python_launch_description_source import (
24 | PythonLaunchDescriptionSource,
25 | )
26 | from launch.actions.include_launch_description import IncludeLaunchDescription
27 | from ament_index_python.packages import get_package_share_directory
28 |
29 |
30 | # Launch all of the robot visualisation launch files one by one
31 | @pytest.mark.launch_test
32 | @launch_testing.markers.keep_alive
33 | def generate_test_description():
34 | return launch.LaunchDescription(
35 | [
36 | IncludeLaunchDescription(
37 | PythonLaunchDescriptionSource(
38 | [
39 | get_package_share_directory("kuka_sunrise_fri_driver"),
40 | "/launch/",
41 | "startup.launch.py",
42 | ]
43 | ),
44 | launch_arguments={
45 | "cm_log_level": "INFO",
46 | }.items(),
47 | ),
48 | launch_testing.actions.ReadyToTest(),
49 | ]
50 | )
51 |
52 |
53 | class TestDriverStartup(unittest.TestCase):
54 | def test_read_stdout(self, proc_output):
55 | # Check for successful initialization
56 | proc_output.assertWaitFor("Robot initialized", timeout=5)
57 | proc_output.assertWaitFor(
58 | "Successful initialization of hardware 'lbr_iiwa14_r820'", timeout=5
59 | )
60 | # Check whether disabling automatic activation was successful
61 | proc_output.assertWaitFor(
62 | "Setting component 'lbr_iiwa14_r820' to 'unconfigured' state.", timeout=5
63 | )
64 |
--------------------------------------------------------------------------------
/kuka_rsi_driver/test/test_driver_startup_eki_rsi.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 KUKA Hungaria Kft.
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 | import unittest
16 |
17 | import launch
18 | import launch_testing.actions
19 | import launch_testing.markers
20 | import pytest
21 | from ament_index_python.packages import get_package_share_directory
22 | from launch.actions.include_launch_description import IncludeLaunchDescription
23 | from launch.launch_description_sources.python_launch_description_source import (
24 | PythonLaunchDescriptionSource,
25 | )
26 |
27 |
28 | # Launch all of the robot visualisation launch files one by one
29 | @pytest.mark.launch_test
30 | @launch_testing.markers.keep_alive
31 | def generate_test_description():
32 | return launch.LaunchDescription(
33 | [
34 | IncludeLaunchDescription(
35 | PythonLaunchDescriptionSource(
36 | [
37 | get_package_share_directory("kuka_rsi_driver"),
38 | "/launch/",
39 | "startup.launch.py",
40 | ]
41 | ),
42 | launch_arguments={
43 | "driver_version": "eki_rsi",
44 | "cm_log_level": "INFO",
45 | }.items(),
46 | ),
47 | launch_testing.actions.ReadyToTest(),
48 | ]
49 | )
50 |
51 |
52 | class TestDriverStartup(unittest.TestCase):
53 | def test_read_stdout(self, proc_output):
54 | # Check for successful initialization
55 | proc_output.assertWaitFor("Robot initialized", timeout=5)
56 | proc_output.assertWaitFor(
57 | "Successful initialization of hardware 'kr6_r700_sixx'", timeout=5
58 | )
59 | # Check whether disabling automatic activation was successful
60 | proc_output.assertWaitFor(
61 | "Setting component 'kr6_r700_sixx' to 'unconfigured' state.", timeout=5
62 | )
63 |
--------------------------------------------------------------------------------
/kuka_rsi_driver/test/test_driver_startup_mxa_rsi.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 KUKA Hungaria Kft.
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 | import unittest
16 |
17 | import launch
18 | import launch_testing.actions
19 | import launch_testing.markers
20 | import pytest
21 | from ament_index_python.packages import get_package_share_directory
22 | from launch.actions.include_launch_description import IncludeLaunchDescription
23 | from launch.launch_description_sources.python_launch_description_source import (
24 | PythonLaunchDescriptionSource,
25 | )
26 |
27 |
28 | # Launch all of the robot visualisation launch files one by one
29 | @pytest.mark.launch_test
30 | @launch_testing.markers.keep_alive
31 | def generate_test_description():
32 | return launch.LaunchDescription(
33 | [
34 | IncludeLaunchDescription(
35 | PythonLaunchDescriptionSource(
36 | [
37 | get_package_share_directory("kuka_rsi_driver"),
38 | "/launch/",
39 | "startup.launch.py",
40 | ]
41 | ),
42 | launch_arguments={
43 | "driver_version": "mxa_rsi",
44 | "cm_log_level": "INFO",
45 | }.items(),
46 | ),
47 | launch_testing.actions.ReadyToTest(),
48 | ]
49 | )
50 |
51 |
52 | class TestDriverStartup(unittest.TestCase):
53 | def test_read_stdout(self, proc_output):
54 | # Check for successful initialization
55 | proc_output.assertWaitFor("Robot initialized", timeout=5)
56 | proc_output.assertWaitFor(
57 | "Successful initialization of hardware 'kr6_r700_sixx'", timeout=5
58 | )
59 | # Check whether disabling automatic activation was successful
60 | proc_output.assertWaitFor(
61 | "Setting component 'kr6_r700_sixx' to 'unconfigured' state.", timeout=5
62 | )
63 |
--------------------------------------------------------------------------------
/kuka_rsi_driver/test/test_driver_startup_rsi_only.py:
--------------------------------------------------------------------------------
1 | # Copyright 2024 KUKA Hungaria Kft.
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 | import unittest
16 |
17 | import launch
18 | import launch_testing.actions
19 | import launch_testing.markers
20 | import pytest
21 | from ament_index_python.packages import get_package_share_directory
22 | from launch.actions.include_launch_description import IncludeLaunchDescription
23 | from launch.launch_description_sources.python_launch_description_source import (
24 | PythonLaunchDescriptionSource,
25 | )
26 |
27 |
28 | # Launch all of the robot visualisation launch files one by one
29 | @pytest.mark.launch_test
30 | @launch_testing.markers.keep_alive
31 | def generate_test_description():
32 | return launch.LaunchDescription(
33 | [
34 | IncludeLaunchDescription(
35 | PythonLaunchDescriptionSource(
36 | [
37 | get_package_share_directory("kuka_rsi_driver"),
38 | "/launch/",
39 | "startup.launch.py",
40 | ]
41 | ),
42 | launch_arguments={
43 | "driver_version": "rsi_only",
44 | "cm_log_level": "INFO",
45 | }.items(),
46 | ),
47 | launch_testing.actions.ReadyToTest(),
48 | ]
49 | )
50 |
51 |
52 | class TestDriverStartup(unittest.TestCase):
53 | def test_read_stdout(self, proc_output):
54 | # Check for successful initialization
55 | proc_output.assertWaitFor("Robot initialized", timeout=5)
56 | proc_output.assertWaitFor(
57 | "Successful initialization of hardware 'kr6_r700_sixx'", timeout=5
58 | )
59 | # Check whether disabling automatic activation was successful
60 | proc_output.assertWaitFor(
61 | "Setting component 'kr6_r700_sixx' to 'unconfigured' state.", timeout=5
62 | )
63 |
--------------------------------------------------------------------------------
/kuka_drivers_core/include/communication_helpers/service_tools.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Zoltán Rési
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 | #ifndef COMMUNICATION_HELPERS__SERVICE_TOOLS_HPP_
16 | #define COMMUNICATION_HELPERS__SERVICE_TOOLS_HPP_
17 |
18 | #include
19 | #include
20 |
21 | #include "rclcpp/rclcpp.hpp"
22 |
23 | namespace kuka_drivers_core
24 | {
25 | template
26 | std::future_status wait_for_result(FutureT & future, WaitTimeT time_to_wait)
27 | {
28 | auto end = std::chrono::steady_clock::now() + time_to_wait;
29 | std::chrono::milliseconds wait_period(100);
30 | std::future_status status = std::future_status::timeout;
31 | do
32 | {
33 | auto now = std::chrono::steady_clock::now();
34 | auto time_left = end - now;
35 | if (time_left <= std::chrono::seconds(0))
36 | {
37 | break;
38 | }
39 | status = future.wait_for((time_left < wait_period) ? time_left : wait_period);
40 | } while (rclcpp::ok() && status != std::future_status::ready);
41 | return status;
42 | }
43 |
44 | template
45 | std::shared_ptr sendRequest(
46 | ClientT client, RequestT request, const uint32_t & service_timeout_ms = 2000,
47 | const uint32_t & response_timeout_ms = 100)
48 | {
49 | if (
50 | service_timeout_ms && !client->wait_for_service(std::chrono::milliseconds(service_timeout_ms)))
51 | {
52 | printf("Wait for service failed\n");
53 | return nullptr;
54 | }
55 | auto future_result = client->async_send_request(request);
56 | auto future_status =
57 | wait_for_result(future_result, std::chrono::milliseconds(response_timeout_ms));
58 | if (future_status != std::future_status::ready)
59 | {
60 | printf("Request timed out\n");
61 | return nullptr;
62 | }
63 | return future_result.get();
64 | }
65 | } // namespace kuka_drivers_core
66 |
67 | #endif // COMMUNICATION_HELPERS__SERVICE_TOOLS_HPP_
68 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: "Bug Report"
2 | description: Create a new ticket for a bug.
3 | title: "[BUG] - "
4 | labels: [
5 | "bug"
6 | ]
7 | body:
8 | - type: textarea
9 | id: description
10 | attributes:
11 | label: "Description"
12 | description: Please enter an explicit description of your issue
13 | placeholder: Describe your issue in a few sentences
14 | validations:
15 | required: true
16 | - type: dropdown
17 | id: robot-os
18 | attributes:
19 | label: "KUKA robot OS"
20 | description: Version of the KUKA OS are you using
21 | multiple: true
22 | options:
23 | - KSS
24 | - Sunrise
25 | - iiQKA
26 | - type: input
27 | id: os-version
28 | attributes:
29 | label: "KUKA robot OS version"
30 | description: Version of the KUKA robot OS
31 | placeholder: eg. KSS 8.6
32 | validations:
33 | required: true
34 | - type: input
35 | id: if-version
36 | attributes:
37 | label: "KUKA external interface version"
38 | description: Version of the KUKA external interface
39 | placeholder: eg. RSI 4.1.3
40 | validations:
41 | required: true
42 | - type: input
43 | id: robot-model
44 | attributes:
45 | label: "Affected robot model(s)"
46 | description: Robot model the issue came up with
47 | placeholder: eg. KR10 R1100-2
48 | validations:
49 | required: true
50 | - type: input
51 | id: driver-version
52 | attributes:
53 | label: "Version or commit hash of the driver"
54 | description: If the issue came up with an older version (not master), provide the release version or commit hash
55 | validations:
56 | required: false
57 | - type: textarea
58 | id: setup
59 | attributes:
60 | label: "Setup"
61 | description: Describe your setup, launch files and executables started (optionally attach rqt_graph output), modifications to code
62 | render: bash
63 | validations:
64 | required: true
65 | - type: textarea
66 | id: reprod
67 | attributes:
68 | label: "Reproduction steps"
69 | description: Clear and ordered steps of reporoducing
70 | render: bash
71 | validations:
72 | required: true
73 | - type: textarea
74 | id: logs
75 | attributes:
76 | label: "Logs"
77 | description: Attach relevant log output here, mentioning if lines were omitted to help readability.
78 | render: bash
79 | validations:
80 | required: false
81 |
--------------------------------------------------------------------------------
/controllers/kuka_event_broadcaster/include/kuka_event_broadcaster/kuka_event_broadcaster.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2024 KUKA Hungaria Kft.
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 | #ifndef KUKA_EVENT_BROADCASTER__KUKA_EVENT_BROADCASTER_HPP_
16 | #define KUKA_EVENT_BROADCASTER__KUKA_EVENT_BROADCASTER_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "controller_interface/controller_interface.hpp"
23 | #include "pluginlib/class_list_macros.hpp"
24 | #include "rclcpp/duration.hpp"
25 | #include "rclcpp/time.hpp"
26 | #include "std_msgs/msg/u_int8.hpp"
27 |
28 | #include "kuka_event_broadcaster/visibility_control.h"
29 |
30 | namespace kuka_controllers
31 | {
32 | class EventBroadcaster : public controller_interface::ControllerInterface
33 | {
34 | public:
35 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::InterfaceConfiguration
36 | command_interface_configuration() const override;
37 |
38 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::InterfaceConfiguration
39 | state_interface_configuration() const override;
40 |
41 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::return_type update(
42 | const rclcpp::Time & time, const rclcpp::Duration & period) override;
43 |
44 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_configure(
45 | const rclcpp_lifecycle::State & previous_state) override;
46 |
47 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_activate(
48 | const rclcpp_lifecycle::State & previous_state) override;
49 |
50 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_deactivate(
51 | const rclcpp_lifecycle::State & previous_state) override;
52 |
53 | KUKA_EVENT_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_init() override;
54 |
55 | private:
56 | rclcpp::Publisher::SharedPtr event_publisher_;
57 | std_msgs::msg::UInt8 event_msg_;
58 | int last_event_ = 0;
59 | };
60 | } // namespace kuka_controllers
61 | #endif // KUKA_EVENT_BROADCASTER__KUKA_EVENT_BROADCASTER_HPP_
62 |
--------------------------------------------------------------------------------
/controllers/fri_state_broadcaster/include/fri_state_broadcaster/fri_state_broadcaster.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 KUKA Hungaria Kft.
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 | #ifndef FRI_STATE_BROADCASTER__FRI_STATE_BROADCASTER_HPP_
16 | #define FRI_STATE_BROADCASTER__FRI_STATE_BROADCASTER_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "controller_interface/controller_interface.hpp"
23 | #include "kuka_driver_interfaces/msg/fri_state.hpp"
24 | #include "pluginlib/class_list_macros.hpp"
25 | #include "rclcpp/duration.hpp"
26 | #include "rclcpp/time.hpp"
27 |
28 | #include "fri_state_broadcaster/visibility_control.h"
29 |
30 | namespace kuka_controllers
31 | {
32 | class FRIStateBroadcaster : public controller_interface::ControllerInterface
33 | {
34 | public:
35 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::InterfaceConfiguration
36 | command_interface_configuration() const override;
37 |
38 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::InterfaceConfiguration
39 | state_interface_configuration() const override;
40 |
41 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::return_type update(
42 | const rclcpp::Time & time, const rclcpp::Duration & period) override;
43 |
44 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_configure(
45 | const rclcpp_lifecycle::State & previous_state) override;
46 |
47 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_activate(
48 | const rclcpp_lifecycle::State & previous_state) override;
49 |
50 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_deactivate(
51 | const rclcpp_lifecycle::State & previous_state) override;
52 |
53 | FRI_STATE_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_init() override;
54 |
55 | private:
56 | int counter_ = 0;
57 | rclcpp::Publisher::SharedPtr robot_state_publisher_;
58 | kuka_driver_interfaces::msg::FRIState state_msg_;
59 | };
60 | } // namespace kuka_controllers
61 | #endif // FRI_STATE_BROADCASTER__FRI_STATE_BROADCASTER_HPP_
62 |
--------------------------------------------------------------------------------
/kuka_iiqka_eac_driver/include/kuka_iiqka_eac_driver/event_observer.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2024 Márk Szitanics
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 | #ifndef KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_
16 | #define KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_
17 |
18 | #include
19 | #include "rclcpp/macros.hpp"
20 |
21 | #include "kuka/external-control-sdk/iiqka/sdk.h"
22 | #include "kuka_drivers_core/hardware_event.hpp"
23 | #include "kuka_iiqka_eac_driver/hardware_interface.hpp"
24 |
25 | namespace kuka_eac
26 | {
27 | class KukaEACEventObserver : public kuka::external::control::EventHandler
28 | {
29 | public:
30 | explicit KukaEACEventObserver(KukaEACHardwareInterface * hw_interface)
31 | : hw_interface_(hw_interface)
32 | {
33 | }
34 | void OnSampling() override
35 | {
36 | hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_STARTED);
37 | RCLCPP_INFO(rclcpp::get_logger("KukaEACHardwareInterface"), "External control is active");
38 | }
39 | void OnControlModeSwitch(const std::string &) override
40 | {
41 | hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_MODE_SWITCH);
42 | RCLCPP_INFO(
43 | rclcpp::get_logger("KukaEACHardwareInterface"), "Control mode switch is in progress");
44 | hw_interface_->reset_cycle_count();
45 | }
46 | void OnStopped(const std::string &) override
47 | {
48 | hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_STOPPED);
49 | RCLCPP_INFO(rclcpp::get_logger("KukaEACHardwareInterface"), "External control finished");
50 | }
51 | void OnError(const std::string & reason) override
52 | {
53 | hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::ERROR);
54 | RCLCPP_ERROR(
55 | rclcpp::get_logger("KukaEACHardwareInterface"), "External control stopped by an error");
56 | RCLCPP_ERROR(rclcpp::get_logger("KukaEACHardwareInterface"), reason.c_str());
57 | }
58 |
59 | private:
60 | KukaEACHardwareInterface * hw_interface_;
61 | };
62 |
63 | } // namespace kuka_eac
64 |
65 | #endif // KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_
66 |
--------------------------------------------------------------------------------
/examples/iiqka_moveit_example/src/moveit_constrained_planning_example.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Áron Svastits
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 "iiqka_moveit_example/moveit_example.hpp"
19 |
20 | int main(int argc, char * argv[])
21 | {
22 | // Setup
23 | // Initialize ROS and create the Node
24 | rclcpp::init(argc, argv);
25 | auto const example_node = std::make_shared();
26 | rclcpp::executors::SingleThreadedExecutor executor;
27 | executor.add_node(example_node);
28 | std::thread([&executor]() { executor.spin(); }).detach();
29 |
30 | example_node->initialize();
31 |
32 | // Add robot platform
33 | example_node->addRobotPlatform();
34 |
35 | // Go to correct position for the example
36 | auto init_trajectory = example_node->planToPosition(
37 | std::vector{0.0017, -2.096, 1.514, 0.0012, -0.9888, -0.0029});
38 | if (init_trajectory != nullptr)
39 | {
40 | example_node->moveGroupInterface()->execute(*init_trajectory);
41 | }
42 |
43 | // Add collision object
44 | example_node->addCollisionBox(
45 | geometry_msgs::build().x(0.125).y(0.15).z(0.5),
46 | geometry_msgs::build().x(0.1).y(1.0).z(0.1));
47 | example_node->addBreakPoint();
48 |
49 | auto cart_goal =
50 | Eigen::Isometry3d(Eigen::Translation3d(0.4, -0.15, 0.55) * Eigen::Quaterniond::Identity());
51 |
52 | geometry_msgs::msg::Quaternion q;
53 | q.x = 0;
54 | q.y = 0;
55 | q.z = 0;
56 | q.w = 1;
57 |
58 | example_node->moveGroupInterface()->setPlanningTime(30.0);
59 |
60 | example_node->setOrientationConstraint(q);
61 | // Plan with collision avoidance
62 | auto planned_trajectory =
63 | example_node->planToPointUntilSuccess(cart_goal, "ompl", "RRTkConfigDefault");
64 | if (planned_trajectory != nullptr)
65 | {
66 | example_node->drawTrajectory(*planned_trajectory);
67 | example_node->addBreakPoint();
68 | example_node->moveGroupInterface()->execute(*planned_trajectory);
69 | }
70 |
71 | // Shutdown ROS
72 | rclcpp::shutdown();
73 | return 0;
74 | }
75 |
--------------------------------------------------------------------------------
/controllers/fri_configuration_controller/include/fri_configuration_controller/fri_configuration_controller.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 KUKA Hungaria Kft.
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 | #ifndef FRI_CONFIGURATION_CONTROLLER__FRI_CONFIGURATION_CONTROLLER_HPP_
16 | #define FRI_CONFIGURATION_CONTROLLER__FRI_CONFIGURATION_CONTROLLER_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "controller_interface/controller_interface.hpp"
23 | #include "kuka_driver_interfaces/msg/fri_configuration.hpp"
24 | #include "pluginlib/class_list_macros.hpp"
25 | #include "rclcpp/duration.hpp"
26 | #include "rclcpp/time.hpp"
27 |
28 | #include "fri_configuration_controller/visibility_control.h"
29 |
30 | namespace kuka_controllers
31 | {
32 | class FRIConfigurationController : public controller_interface::ControllerInterface
33 | {
34 | public:
35 | FRI_CONFIGURATION_CONTROLLER_PUBLIC
36 | controller_interface::InterfaceConfiguration command_interface_configuration() const override;
37 |
38 | FRI_CONFIGURATION_CONTROLLER_PUBLIC
39 | controller_interface::InterfaceConfiguration state_interface_configuration() const override;
40 |
41 | FRI_CONFIGURATION_CONTROLLER_PUBLIC controller_interface::return_type update(
42 | const rclcpp::Time & time, const rclcpp::Duration & period) override;
43 |
44 | FRI_CONFIGURATION_CONTROLLER_PUBLIC controller_interface::CallbackReturn on_configure(
45 | const rclcpp_lifecycle::State & previous_state) override;
46 |
47 | FRI_CONFIGURATION_CONTROLLER_PUBLIC controller_interface::CallbackReturn on_activate(
48 | const rclcpp_lifecycle::State & previous_state) override;
49 |
50 | FRI_CONFIGURATION_CONTROLLER_PUBLIC controller_interface::CallbackReturn on_deactivate(
51 | const rclcpp_lifecycle::State & previous_state) override;
52 |
53 | FRI_CONFIGURATION_CONTROLLER_PUBLIC controller_interface::CallbackReturn on_init() override;
54 |
55 | private:
56 | rclcpp::Subscription::SharedPtr fri_config_sub_;
57 | double receive_multiplier_ = 1;
58 | double send_period_ms_ = 10;
59 | };
60 | } // namespace kuka_controllers
61 | #endif // FRI_CONFIGURATION_CONTROLLER__FRI_CONFIGURATION_CONTROLLER_HPP_
62 |
--------------------------------------------------------------------------------
/controllers/kuka_control_mode_handler/include/kuka_control_mode_handler/kuka_control_mode_handler.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 KUKA Hungaria Kft.
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 | #ifndef KUKA_CONTROL_MODE_HANDLER__KUKA_CONTROL_MODE_HANDLER_HPP_
16 | #define KUKA_CONTROL_MODE_HANDLER__KUKA_CONTROL_MODE_HANDLER_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "controller_interface/controller_interface.hpp"
24 | #include "kuka_drivers_core/control_mode.hpp"
25 | #include "pluginlib/class_list_macros.hpp"
26 | #include "rclcpp/duration.hpp"
27 | #include "rclcpp/time.hpp"
28 | #include "std_msgs/msg/u_int32.hpp"
29 |
30 | #include "kuka_control_mode_handler/visibility_control.h"
31 |
32 | namespace kuka_controllers
33 | {
34 | class ControlModeHandler : public controller_interface::ControllerInterface
35 | {
36 | public:
37 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::InterfaceConfiguration
38 | command_interface_configuration() const override;
39 |
40 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::InterfaceConfiguration
41 | state_interface_configuration() const override;
42 |
43 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::return_type update(
44 | const rclcpp::Time & time, const rclcpp::Duration & period) override;
45 |
46 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::CallbackReturn on_configure(
47 | const rclcpp_lifecycle::State & previous_state) override;
48 |
49 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::CallbackReturn on_activate(
50 | const rclcpp_lifecycle::State & previous_state) override;
51 |
52 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::CallbackReturn on_deactivate(
53 | const rclcpp_lifecycle::State & previous_state) override;
54 |
55 | KUKA_CONTROL_MODE_HANDLER_PUBLIC controller_interface::CallbackReturn on_init() override;
56 |
57 | private:
58 | rclcpp::Subscription::SharedPtr control_mode_subscriber_;
59 | std::atomic control_mode_ =
60 | kuka_drivers_core::ControlMode::CONTROL_MODE_UNSPECIFIED;
61 | };
62 | } // namespace kuka_controllers
63 | #endif // KUKA_CONTROL_MODE_HANDLER__KUKA_CONTROL_MODE_HANDLER_HPP_
64 |
--------------------------------------------------------------------------------
/kuka_drivers_core/include/communication_helpers/ros2_control_tools.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Aron Svastits
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 | #ifndef COMMUNICATION_HELPERS__ROS2_CONTROL_TOOLS_HPP_
16 | #define COMMUNICATION_HELPERS__ROS2_CONTROL_TOOLS_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "communication_helpers/service_tools.hpp"
23 | #include "controller_manager_msgs/srv/set_hardware_component_state.hpp"
24 | #include "controller_manager_msgs/srv/switch_controller.hpp"
25 | #include "rclcpp/rclcpp.hpp"
26 |
27 | namespace kuka_drivers_core
28 | {
29 |
30 | inline bool changeHardwareState(
31 | rclcpp::Client::SharedPtr client,
32 | const std::string & hardware_name, uint8_t state, int timeout_ms = 2000)
33 | {
34 | auto hw_request =
35 | std::make_shared();
36 | hw_request->name = hardware_name;
37 | hw_request->target_state.id = state;
38 | auto hw_response = sendRequest(
39 | client, hw_request, 0, timeout_ms);
40 | if (!hw_response || !hw_response->ok)
41 | {
42 | return false;
43 | }
44 | return true;
45 | }
46 |
47 | inline bool changeControllerState(
48 | rclcpp::Client::SharedPtr client,
49 | const std::vector & activate_controllers,
50 | const std::vector & deactivate_controllers,
51 | int32_t strictness = controller_manager_msgs::srv::SwitchController::Request::STRICT)
52 | {
53 | auto controller_request =
54 | std::make_shared();
55 | controller_request->strictness = strictness;
56 | controller_request->activate_controllers = activate_controllers;
57 | controller_request->deactivate_controllers = deactivate_controllers;
58 |
59 | auto controller_response = sendRequest(
60 | client, controller_request, 0, 2000);
61 | if (!controller_response || !controller_response->ok)
62 | {
63 | return false;
64 | }
65 | return true;
66 | }
67 | } // namespace kuka_drivers_core
68 |
69 | #endif // COMMUNICATION_HELPERS__ROS2_CONTROL_TOOLS_HPP_
70 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/include/kuka_sunrise_fri_driver/serialization.hpp:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Zoltán Rési
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 | #ifndef KUKA_SUNRISE_FRI_DRIVER__SERIALIZATION_HPP_
16 | #define KUKA_SUNRISE_FRI_DRIVER__SERIALIZATION_HPP_
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | namespace kuka_sunrise_fri_driver
25 | {
26 |
27 | int serializeNext(int integer_in, std::vector & serialized_out)
28 | {
29 | std::uint8_t * bytes = reinterpret_cast(&integer_in);
30 | auto it = serialized_out.end();
31 | serialized_out.insert(it, bytes, bytes + sizeof(int));
32 |
33 | // Redefine iterator because of possible invalidation
34 | auto from_it = std::prev(serialized_out.end(), sizeof(int));
35 | std::reverse(from_it, serialized_out.end());
36 | // TODO(resizoltan): assert that int is 4 bytes long
37 | // TODO(resizoltan): check endianness
38 | return sizeof(int);
39 | }
40 |
41 | int deserializeNext(const std::vector & serialized_in, int & integer_out)
42 | {
43 | if (serialized_in.size() < sizeof(int))
44 | {
45 | // TODO(resizoltan): error
46 | }
47 | std::vector serialized_copy = serialized_in;
48 | integer_out = *(reinterpret_cast(serialized_copy.data()));
49 | return sizeof(int);
50 | }
51 |
52 | int serializeNext(double double_in, std::vector & serialized_out)
53 | {
54 | std::uint8_t * bytes = reinterpret_cast(&double_in);
55 | serialized_out.insert(serialized_out.end(), bytes, bytes + sizeof(double));
56 |
57 | // Redefine iterator because of possible invalidation
58 | auto from_it = std::prev(serialized_out.end(), sizeof(double));
59 | std::reverse(from_it, serialized_out.end());
60 | // TODO(resizoltan): assert that int is 4 bytes long
61 | // TODO(resizoltan): check endianness
62 | return sizeof(int);
63 | }
64 |
65 | int deserializeNext(const std::vector & serialized_in, double & double_out)
66 | {
67 | if (serialized_in.size() < sizeof(double))
68 | {
69 | // TODO(resizoltan): error
70 | }
71 | std::vector serialized_copy = serialized_in;
72 | double_out = *(reinterpret_cast(serialized_copy.data()));
73 | return sizeof(int);
74 | }
75 | } // namespace kuka_sunrise_fri_driver
76 |
77 | #endif // KUKA_SUNRISE_FRI_DRIVER__SERIALIZATION_HPP_
78 |
--------------------------------------------------------------------------------
/controllers/kuka_event_broadcaster/src/kuka_event_broadcaster.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2024 KUKA Hungaria Kft.
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 "kuka_drivers_core/hardware_interface_types.hpp"
16 |
17 | #include "kuka_event_broadcaster/kuka_event_broadcaster.hpp"
18 |
19 | namespace kuka_controllers
20 | {
21 | controller_interface::CallbackReturn EventBroadcaster::on_init()
22 | {
23 | event_publisher_ = get_node()->create_publisher(
24 | "~/hardware_event", rclcpp::SystemDefaultsQoS());
25 | return controller_interface::CallbackReturn::SUCCESS;
26 | }
27 |
28 | controller_interface::InterfaceConfiguration EventBroadcaster::command_interface_configuration()
29 | const
30 | {
31 | return controller_interface::InterfaceConfiguration{
32 | controller_interface::interface_configuration_type::NONE};
33 | }
34 |
35 | controller_interface::InterfaceConfiguration EventBroadcaster::state_interface_configuration() const
36 | {
37 | controller_interface::InterfaceConfiguration config;
38 | config.type = controller_interface::interface_configuration_type::INDIVIDUAL;
39 | config.names.emplace_back(
40 | std::string(hardware_interface::STATE_PREFIX) + "/" + hardware_interface::SERVER_STATE);
41 | return config;
42 | }
43 |
44 | controller_interface::CallbackReturn EventBroadcaster::on_configure(const rclcpp_lifecycle::State &)
45 | {
46 | return controller_interface::CallbackReturn::SUCCESS;
47 | }
48 |
49 | controller_interface::CallbackReturn EventBroadcaster::on_activate(const rclcpp_lifecycle::State &)
50 | {
51 | return controller_interface::CallbackReturn::SUCCESS;
52 | }
53 |
54 | controller_interface::CallbackReturn EventBroadcaster::on_deactivate(
55 | const rclcpp_lifecycle::State &)
56 | {
57 | return controller_interface::CallbackReturn::SUCCESS;
58 | }
59 |
60 | controller_interface::return_type EventBroadcaster::update(
61 | const rclcpp::Time &, const rclcpp::Duration &)
62 | {
63 | auto current_event =
64 | static_cast(state_interfaces_[0].get_optional().value_or(last_event_));
65 | if (current_event != last_event_)
66 | {
67 | event_msg_.data = current_event;
68 | event_publisher_->publish(event_msg_);
69 | last_event_ = current_event;
70 | }
71 | return controller_interface::return_type::OK;
72 | }
73 | } // namespace kuka_controllers
74 |
75 | PLUGINLIB_EXPORT_CLASS(
76 | kuka_controllers::EventBroadcaster, controller_interface::ControllerInterface)
77 |
--------------------------------------------------------------------------------
/kuka_rsi_driver/src/hardware_interface_rsi_only.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2023 KUKA Hungaria Kft.
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 |
17 | #include "hardware_interface/types/hardware_interface_type_values.hpp"
18 | #include "pluginlib/class_list_macros.hpp"
19 |
20 | #include "kuka_drivers_core/hardware_event.hpp"
21 | #include "kuka_drivers_core/hardware_interface_types.hpp"
22 | #include "kuka_rsi_driver/hardware_interface_rsi_only.hpp"
23 |
24 | namespace kuka_rsi_driver
25 | {
26 | CallbackReturn KukaRSIHardwareInterface::on_configure(const rclcpp_lifecycle::State &)
27 | {
28 | kuka::external::control::kss::Configuration rsi_config;
29 | rsi_config.installed_interface =
30 | kuka::external::control::kss::Configuration::InstalledInterface::RSI_ONLY;
31 | const bool setup_success = SetupRobot(rsi_config, nullptr, nullptr);
32 | return setup_success ? CallbackReturn::SUCCESS : CallbackReturn::ERROR;
33 | }
34 |
35 | CallbackReturn KukaRSIHardwareInterface::on_activate(const rclcpp_lifecycle::State &)
36 | {
37 | Read(10 * READ_TIMEOUT_MS);
38 |
39 | std::copy(hw_states_.cbegin(), hw_states_.cend(), hw_commands_.begin());
40 | CopyGPIOStatesToCommands();
41 |
42 | Write();
43 |
44 | msg_received_ = false;
45 | is_active_ = true;
46 |
47 | RCLCPP_INFO(logger_, "Received position data from robot controller!");
48 | set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_STARTED);
49 |
50 | return CallbackReturn::SUCCESS;
51 | }
52 |
53 | CallbackReturn KukaRSIHardwareInterface::on_deactivate(const rclcpp_lifecycle::State &)
54 | {
55 | // If control is active, send stop signal
56 | if (msg_received_)
57 | {
58 | RCLCPP_INFO(logger_, "Deactivating hardware interface by sending stop signal");
59 |
60 | // StopControlling sometimes calls a blocking read, which could conflict with the read() method,
61 | // but resource manager handles locking (resources_lock_), so is not necessary here
62 | robot_ptr_->StopControlling();
63 | }
64 |
65 | is_active_ = false;
66 | msg_received_ = false;
67 |
68 | RCLCPP_INFO(logger_, "Stop requested!");
69 | return CallbackReturn::SUCCESS;
70 | }
71 |
72 | void KukaRSIHardwareInterface::CreateRobotInstance(
73 | const kuka::external::control::kss::Configuration & config)
74 | {
75 | robot_ptr_ = std::make_unique(config);
76 | }
77 | } // namespace kuka_rsi_driver
78 |
79 | PLUGINLIB_EXPORT_CLASS(
80 | kuka_rsi_driver::KukaRSIHardwareInterface, hardware_interface::SystemInterface)
81 |
--------------------------------------------------------------------------------
/kuka_drivers_core/src/parameter_handler.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2020 Gergely Kovács
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 "kuka_drivers_core/parameter_handler.hpp"
16 |
17 | #include
18 | #include
19 | #include
20 |
21 | namespace kuka_drivers_core
22 | {
23 | ParameterHandler::ParameterHandler(rclcpp_lifecycle::LifecycleNode * node) : node_(node) {}
24 |
25 | rcl_interfaces::msg::SetParametersResult ParameterHandler::onParamChange(
26 | const std::vector & parameters) const
27 | {
28 | rcl_interfaces::msg::SetParametersResult result;
29 | result.successful = false;
30 | for (const rclcpp::Parameter & param : parameters)
31 | {
32 | auto found_param_it = std::find_if(
33 | params_.begin(), params_.end(),
34 | [¶m](auto param_ptr) { return param_ptr->getName() == param.get_name(); });
35 | // When used properly, we should not reach this
36 | // but better to keep additional check to filter improper use
37 | if (found_param_it == params_.end())
38 | {
39 | printf("Invalid parameter name\n");
40 | }
41 | else if (canSetParameter(*(*found_param_it)))
42 | {
43 | result.successful = (*found_param_it)->callCallback(param);
44 | }
45 | }
46 | return result;
47 | }
48 |
49 | bool ParameterHandler::canSetParameter(const ParameterBase & param) const
50 | {
51 | if (node_ == nullptr)
52 | {
53 | // Node is not lifecycle node, parameter can always be set
54 | return true;
55 | }
56 | try
57 | {
58 | if (!param.getRights().isSetAllowed(node_->get_current_state().id()))
59 | {
60 | RCLCPP_ERROR(
61 | node_->get_logger(), "Parameter %s cannot be changed while in state %s",
62 | param.getName().c_str(), node_->get_current_state().label().c_str());
63 | return false;
64 | }
65 | }
66 | catch (const std::out_of_range &)
67 | {
68 | RCLCPP_ERROR(
69 | node_->get_logger(), "Parameter set access rights for parameter %s couldn't be determined",
70 | param.getName().c_str());
71 | return false;
72 | }
73 | return true;
74 | }
75 |
76 | void ParameterHandler::registerParameter(
77 | std::shared_ptr param_shared_ptr, bool block)
78 | {
79 | params_.emplace_back(param_shared_ptr);
80 | param_shared_ptr->getParameterInterface()->declare_parameter(
81 | param_shared_ptr->getName(), param_shared_ptr->getDefaultValue());
82 | if (block)
83 | {
84 | param_shared_ptr->blockParameter();
85 | }
86 | }
87 |
88 | } // namespace kuka_drivers_core
89 |
--------------------------------------------------------------------------------
/kuka_drivers_core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 | project(kuka_drivers_core)
3 |
4 | if(NOT CMAKE_C_STANDARD)
5 | set(CMAKE_C_STANDARD 99)
6 | endif()
7 |
8 | if(NOT CMAKE_CXX_STANDARD)
9 | set(CMAKE_CXX_STANDARD 14)
10 | endif()
11 |
12 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
13 | add_compile_options(-Wall -Wextra -Wpedantic)
14 | endif()
15 |
16 | include_directories(include)
17 |
18 | find_package(ament_cmake REQUIRED)
19 | find_package(rclcpp REQUIRED)
20 | find_package(rclcpp_lifecycle REQUIRED)
21 | find_package(lifecycle_msgs REQUIRED)
22 | find_package(controller_manager REQUIRED)
23 |
24 | add_library(kuka_drivers_core SHARED
25 | src/ros2_base_node.cpp
26 | src/ros2_base_lc_node.cpp
27 | src/parameter_handler.cpp
28 | src/controller_handler.cpp
29 | )
30 | ament_target_dependencies(kuka_drivers_core rclcpp rclcpp_lifecycle lifecycle_msgs)
31 |
32 | add_executable(control_node
33 | src/control_node.cpp)
34 | ament_target_dependencies(control_node rclcpp rclcpp_lifecycle controller_manager)
35 |
36 | ament_export_targets(export_kuka_drivers_core HAS_LIBRARY_TARGET)
37 | ament_export_dependencies(rclcpp rclcpp_lifecycle lifecycle_msgs)
38 | ament_export_libraries(${PROJECT_NAME})
39 |
40 | add_library(communication_helpers SHARED
41 | include/communication_helpers/ros2_control_tools.hpp
42 | include/communication_helpers/service_tools.hpp)
43 | ament_target_dependencies(communication_helpers rclcpp)
44 | set_target_properties(communication_helpers PROPERTIES LINKER_LANGUAGE CXX)
45 |
46 | ament_export_targets(communication_helpers HAS_LIBRARY_TARGET)
47 | ament_export_dependencies(rclcpp)
48 |
49 | install(DIRECTORY include/${PROJECT_NAME}/
50 | DESTINATION include/${PROJECT_NAME}/
51 | )
52 |
53 | install(TARGETS kuka_drivers_core
54 | EXPORT export_kuka_drivers_core
55 | LIBRARY DESTINATION lib
56 | ARCHIVE DESTINATION lib
57 | RUNTIME DESTINATION bin
58 | INCLUDES DESTINATION include)
59 |
60 | install(DIRECTORY include/communication_helpers DESTINATION include)
61 | install(
62 | TARGETS communication_helpers
63 | EXPORT communication_helpers
64 | LIBRARY DESTINATION lib
65 | INCLUDES DESTINATION include
66 | )
67 |
68 | install(TARGETS ${PROJECT_NAME} control_node
69 | DESTINATION lib/${PROJECT_NAME})
70 |
71 | ament_export_include_directories(include)
72 |
73 | if(BUILD_TESTING)
74 |
75 | endif()
76 |
77 | ament_package()
78 |
79 | set(SONARQUBE_PACKAGES_FILE "none" CACHE STRING "Path to the file that contains the package source directories for SonarQube.")
80 | option(TEST_COVERAGE "Generate test coverage reports upon testing." OFF)
81 |
82 | if(NOT ${SONARQUBE_PACKAGES_FILE} MATCHES "none")
83 | file(APPEND ${SONARQUBE_PACKAGES_FILE} "${PROJECT_NAME};${PROJECT_SOURCE_DIR}\n")
84 | message(${SONARQUBE_PACKAGES_FILE})
85 | endif()
86 |
87 | if(TEST_COVERAGE)
88 | set(CMAKE_BUILD_TYPE Debug)
89 | list(APPEND CMAKE_MODULE_PATH "/usr/lib/cmake/CodeCoverage")
90 | include(CodeCoverage)
91 | append_coverage_compiler_flags()
92 | set_coverage_output_dir()
93 | endif()
94 |
95 | if(TEST_COVERAGE)
96 | endif()
97 |
--------------------------------------------------------------------------------
/kuka_sunrise_fri_driver/robot_application/src/ros2/serialization/ControlModeParams.java:
--------------------------------------------------------------------------------
1 | package ros2.serialization;
2 |
3 | import java.io.Externalizable;
4 | import java.io.IOException;
5 | import java.io.ObjectInput;
6 | import java.io.ObjectOutput;
7 | import java.util.Arrays;
8 |
9 |
10 | import com.kuka.roboticsAPI.motionModel.controlModeModel.IMotionControlMode;
11 | import com.kuka.roboticsAPI.motionModel.controlModeModel.JointImpedanceControlMode;
12 | import com.kuka.roboticsAPI.motionModel.controlModeModel.PositionControlMode;
13 |
14 | public abstract class ControlModeParams implements Externalizable{
15 | public static int length = 0;
16 |
17 | private enum ControlModeID{
18 | POSITION( (byte)1),
19 | JOINT_IMPEDANCE((byte)2);
20 |
21 | public final byte value;
22 |
23 | ControlModeID(byte value){
24 | this.value = value;
25 | }
26 |
27 | public static ControlModeID fromByte(byte value){
28 | for(ControlModeID id : ControlModeID.values()){
29 | if(value == id.value){
30 | return id;
31 | }
32 | }
33 | throw new RuntimeException("Byte " + value + " does not represent an ControlModeID");
34 | }
35 | }
36 |
37 | public static ControlModeParams fromSerialData(byte[] serialData){
38 | if(serialData.length == 0){
39 | throw new RuntimeException("serialData is empty");
40 | }
41 | ControlModeID controlModeID = ControlModeID.fromByte(serialData[0]);
42 | ControlModeParams controlModeParams = null;
43 | switch(controlModeID){
44 | case POSITION:
45 | controlModeParams = new PositionControlModeParams();
46 | break;
47 | case JOINT_IMPEDANCE:
48 | controlModeParams = new JointImpedanceControlModeParams();
49 | break;
50 | }
51 | serialData = Arrays.copyOfRange(serialData, 1, serialData.length);
52 | MessageEncoding.Decode(serialData, controlModeParams);
53 | return controlModeParams;
54 | }
55 |
56 | public static ControlModeParams fromMotionControlMode(IMotionControlMode controlMode){
57 | if(controlMode == null){
58 | throw new RuntimeException("ControlMode is null");
59 | }
60 | ControlModeParams controlModeParams;
61 | if(controlMode instanceof PositionControlMode){
62 | controlModeParams = new PositionControlModeParams();
63 | } else if (controlMode instanceof JointImpedanceControlMode){
64 | controlModeParams = new JointImpedanceControlModeParams((JointImpedanceControlMode) controlMode);
65 | } else {
66 | throw new RuntimeException("Control mode not supported");
67 | }
68 | return controlModeParams;
69 | }
70 |
71 | @Override
72 | public void writeExternal(ObjectOutput out) throws IOException {
73 |
74 |
75 | }
76 |
77 | @Override
78 | public void readExternal(ObjectInput in) throws IOException,
79 | ClassNotFoundException {
80 |
81 | }
82 |
83 | }
84 |
85 | class PositionControlModeParams extends ControlModeParams{
86 |
87 |
88 | }
89 |
90 | class JointImpedanceControlModeParams extends ControlModeParams{
91 | public JointImpedanceControlModeParams(){
92 |
93 | }
94 | public JointImpedanceControlModeParams(JointImpedanceControlMode controlMode){
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/controllers/joint_group_impedance_controller/src/joint_group_impedance_controller.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 KUKA Hungaria Kft.
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 "pluginlib/class_list_macros.hpp"
16 |
17 | #include "kuka_drivers_core/hardware_interface_types.hpp"
18 |
19 | #include "joint_group_impedance_controller/joint_group_impedance_controller.hpp"
20 |
21 | namespace kuka_controllers
22 | {
23 |
24 | JointGroupImpedanceController::JointGroupImpedanceController() : ForwardControllersBase() {}
25 |
26 | void JointGroupImpedanceController::declare_parameters()
27 | {
28 | param_listener_ = std::make_shared(get_node());
29 | }
30 |
31 | controller_interface::CallbackReturn JointGroupImpedanceController::read_parameters()
32 | {
33 | if (!param_listener_)
34 | {
35 | RCLCPP_ERROR(get_node()->get_logger(), "Error encountered during init");
36 | return controller_interface::CallbackReturn::ERROR;
37 | }
38 | params_ = param_listener_->get_params();
39 |
40 | if (params_.joints.empty())
41 | {
42 | RCLCPP_ERROR(get_node()->get_logger(), "'joints' parameter is empty");
43 | return controller_interface::CallbackReturn::ERROR;
44 | }
45 |
46 | if (params_.interface_names.empty())
47 | {
48 | RCLCPP_ERROR(get_node()->get_logger(), "'interfaces' parameter is empty");
49 | return controller_interface::CallbackReturn::ERROR;
50 | }
51 |
52 | for (const auto & joint : params_.joints)
53 | {
54 | for (const auto & interface : params_.interface_names)
55 | {
56 | command_interface_types_.push_back(joint + "/" + interface);
57 | }
58 | }
59 |
60 | return controller_interface::CallbackReturn::SUCCESS;
61 | }
62 |
63 | controller_interface::CallbackReturn JointGroupImpedanceController::on_init()
64 | {
65 | auto ret = ForwardControllersBase::on_init();
66 | if (ret != CallbackReturn::SUCCESS)
67 | {
68 | return ret;
69 | }
70 |
71 | try
72 | {
73 | // Explicitly set the interfaces parameter declared by the
74 | // forward_command_controller
75 | get_node()->set_parameter(rclcpp::Parameter(
76 | "interface_names",
77 | std::vector{
78 | hardware_interface::HW_IF_STIFFNESS, hardware_interface::HW_IF_DAMPING}));
79 | }
80 | catch (const std::exception & e)
81 | {
82 | fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what());
83 | return CallbackReturn::ERROR;
84 | }
85 |
86 | return CallbackReturn::SUCCESS;
87 | }
88 | } // namespace kuka_controllers
89 |
90 | PLUGINLIB_EXPORT_CLASS(
91 | kuka_controllers::JointGroupImpedanceController, controller_interface::ControllerInterface)
92 |
--------------------------------------------------------------------------------
/kuka_drivers_core/src/control_node.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2022 KUKA Hungaria Kft.
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 "controller_manager/controller_manager.hpp"
19 | #include "rclcpp/rclcpp.hpp"
20 | #include "std_msgs/msg/bool.hpp"
21 |
22 | int main(int argc, char ** argv)
23 | {
24 | rclcpp::init(argc, argv);
25 | auto executor = std::make_shared();
26 | auto controller_manager =
27 | std::make_shared(executor, "controller_manager");
28 |
29 | auto qos = rclcpp::QoS(rclcpp::KeepLast(1));
30 | qos.best_effort();
31 |
32 | std::atomic_bool is_configured = false;
33 | auto is_configured_sub = controller_manager->create_subscription(
34 | "robot_manager/is_configured", qos,
35 | [&is_configured](std_msgs::msg::Bool::SharedPtr msg) { is_configured = msg->data; });
36 |
37 | std::thread control_loop(
38 | [controller_manager, &is_configured]()
39 | {
40 | struct sched_param param;
41 | param.sched_priority = 95;
42 | if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1)
43 | {
44 | RCLCPP_ERROR(controller_manager->get_logger(), "setscheduler error");
45 | RCLCPP_ERROR(controller_manager->get_logger(), strerror(errno));
46 | RCLCPP_WARN(
47 | controller_manager->get_logger(),
48 | "You can use the driver but scheduler priority was not set");
49 | }
50 |
51 | const rclcpp::Duration dt =
52 | rclcpp::Duration::from_seconds(1.0 / controller_manager->get_update_rate());
53 | std::chrono::milliseconds dt_ms{1000 / controller_manager->get_update_rate()};
54 |
55 | try
56 | {
57 | while (rclcpp::ok())
58 | {
59 | if (is_configured)
60 | {
61 | controller_manager->read(controller_manager->now(), dt);
62 | controller_manager->update(controller_manager->now(), dt);
63 | controller_manager->write(controller_manager->now(), dt);
64 | }
65 | else
66 | {
67 | controller_manager->update(controller_manager->now(), dt);
68 | std::this_thread::sleep_for(dt_ms);
69 | }
70 | }
71 | }
72 | catch (std::exception & e)
73 | {
74 | RCLCPP_ERROR(
75 | controller_manager->get_logger(), "Quitting control loop due to: %s", e.what());
76 | }
77 | });
78 |
79 | executor->add_node(controller_manager);
80 |
81 | executor->spin();
82 | control_loop.join();
83 |
84 | // shutdown
85 | rclcpp::shutdown();
86 |
87 | return 0;
88 | }
89 |
--------------------------------------------------------------------------------