diff --git a/.github/workflows/industrial_ci.yml b/.github/workflows/industrial_ci.yml
index d27e4bda..7662cf30 100644
--- a/.github/workflows/industrial_ci.yml
+++ b/.github/workflows/industrial_ci.yml
@@ -22,6 +22,10 @@ on:
branches:
- master
+ schedule:
+ # Run every Monday at 1PM UTC
+ - cron: 0 13 * * 1
+
jobs:
industrial_ci:
name: ROS-Industrial CI
@@ -32,7 +36,9 @@ jobs:
BUILDER: colcon
ANALYZER: sonarqube
TEST_COVERAGE: true
- UPSTREAM_WORKSPACE: 'github:kroshu/kuka_robot_descriptions#master'
+ # Hacky solution needed to be able to build upstream WS:
+ # kuka_driver_interfaces and kuka_drivers_core must be also added to upstream
+ UPSTREAM_WORKSPACE: 'github:kroshu/kuka_robot_descriptions#master github:kroshu/kuka_controllers#master github:kroshu/kuka_drivers#master -kuka_drivers/examples -kuka_drivers/kuka_drivers -kuka_drivers/kuka_iiqka_eac_driver -kuka_drivers/kuka_kss_rsi_driver -kuka_drivers/kuka_sunrise_fri_driver'
CMAKE_ARGS: '-DMOCK_FRI=ON'
ROS_DISTRO: humble
env:
diff --git a/doc/wiki/KSS_RSI.md b/doc/wiki/KSS_RSI.md
index 697ba9f8..8a940697 100644
--- a/doc/wiki/KSS_RSI.md
+++ b/doc/wiki/KSS_RSI.md
@@ -22,22 +22,13 @@ Windows runs behind the SmartHMI on the teach pad. Make sure that the **Windows
There should already be an interface checked out as the **Windows interface**.
- **Windows interface checkbox** should be checked.
2. Add a new network for RSI:
-
- **KRC4:**
- - Minimize the SmartHMI (**Start-up > Service > Minimize HMI**).
- - Run **RSI-Network** from the Windows Start menu (**All Programs > RSI-Network**).
- - Check that the **Network - Kuka User Interface** shows the Windows interface with the specified IP address.
- - Add a new IP address on another subnet for the **RSI interface**.
- - Select the entry **New** under **RSI Ethernet** in the tree structure and press **Edit**.
- - Enter the IP address and confirm with **OK**.
- - Close **RSI-Network** and maximize the SmartHMI.
-
- **KRC5:**
- - Press the **Advanced** button and **New interface**.
- - Select **Mixed IP address** and keep the default **Receiving task: Target subnet** and **Real-time receiving Task: UDP**
- - Set the IP address to a different subnet then the **KLI interface**.
- - **Default gateway**: leave it empty
- - **Windows interface checkbox** should NOT be checked
+ - Press the **Advanced** button and **New interface**.
+ - Select **Mixed IP address** and keep the default settings:
+ - **Receiving task: Target subnet**
+ - **Real-time receiving Task: UDP**
+ - Set the IP address to a different subnet then the **KLI interface**.
+ - **Default gateway**: leave it empty
+ - **Windows interface checkbox** should NOT be checked
3. Reboot the controller with a cold restart (**Shutdown > Check *Force cold start* and *Reload files* > Reboot control PC**).
@@ -48,7 +39,7 @@ There are 3 files necessary for RSI that are available in the `krl` directory:
- The `IP_NUMBER` tag should be modified so that it corresponds to the IP address previously added for your (real-time) PC.
- The `PORT` might be left as it is (59152), but can be also changed if a different port is to be used on the client machine.
-- `ros_rsi.src`: This contains the KRL program that starts external control and should not be modified.
+- `ros_rsi.src`: This contains the KRL program that starts external control. The program contains a movement to the (0, -90, 90, 0, 90, 0) position, as the first motion instruction in a KRL program must define an unambiguous starting position. The goal position might be modified if necessary, the other parts of the program should be left unchanged.
- `ros_rsi.rsix`: This contains the RSI context (can be visualized with **RSIVisual**). It can be modified for example to add filtering behaviour, but this is not recommended and should be implemented on the client side instead.
- For older RSI versions (<=4.0.3), the context can only be defined in 3 different files: `ros_rsi.rsi.xml`, `ros_rsi.rsi.diagram` and `ros_rsi.rsi`, these can be found under `krl/deprecated`. In this case, these 3 files should be copied to the controller instead of the `ros_rsi.rsix`.
diff --git a/doc/wiki/iiQKA_EAC.md b/doc/wiki/iiQKA_EAC.md
index 86c2524a..28ed0c8b 100644
--- a/doc/wiki/iiQKA_EAC.md
+++ b/doc/wiki/iiQKA_EAC.md
@@ -47,7 +47,7 @@ The IP address of the client machine and robot controller must be provided as a
To start the driver, two launch file are available, with and without `rviz`. To launch (without `rviz`), run:
```
-ros2 launch kuka_iiqka_eac_driver startup.launch.py client_ip:=0.0.0.0 controller_ip=0.0.0.0
+ros2 launch kuka_iiqka_eac_driver startup.launch.py client_ip:=0.0.0.0 controller_ip:=0.0.0.0
```
This starts the 3 core components of every driver (described in the *Non-real-time interface* section of the [project overview](Project%20overview.md)) and the following controllers:
diff --git a/kuka_iiqka_eac_driver/CMakeLists.txt b/kuka_iiqka_eac_driver/CMakeLists.txt
index bf1ffec8..8e702b8c 100644
--- a/kuka_iiqka_eac_driver/CMakeLists.txt
+++ b/kuka_iiqka_eac_driver/CMakeLists.txt
@@ -100,6 +100,7 @@ install(DIRECTORY config launch test
if(BUILD_TESTING)
find_package(launch_testing_ament_cmake)
add_launch_test(test/test_driver_startup.py)
+ add_launch_test(test/test_driver_activation.py)
add_launch_test(test/test_multi_robot_startup.py)
endif()
diff --git a/kuka_iiqka_eac_driver/package.xml b/kuka_iiqka_eac_driver/package.xml
index b97214a3..a57c9f6b 100644
--- a/kuka_iiqka_eac_driver/package.xml
+++ b/kuka_iiqka_eac_driver/package.xml
@@ -28,6 +28,11 @@
kuka_lbr_iisy_support
ros2_control
ros2_controllers
+ joint_group_impedance_controller
+ effort_controllers
+ control_mode_handler
+
+ ros2lifecycle
ament_cmake
diff --git a/kuka_iiqka_eac_driver/test/test_driver_activation.py b/kuka_iiqka_eac_driver/test/test_driver_activation.py
new file mode 100644
index 00000000..91ffbc59
--- /dev/null
+++ b/kuka_iiqka_eac_driver/test/test_driver_activation.py
@@ -0,0 +1,81 @@
+# Copyright 2024 Áron Svastits
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+import launch
+import launch.actions
+import launch_testing.actions
+import launch_testing.markers
+import pytest
+
+from launch.launch_description_sources.python_launch_description_source import (
+ PythonLaunchDescriptionSource,
+)
+from launch.actions.include_launch_description import IncludeLaunchDescription
+from ament_index_python.packages import get_package_share_directory
+
+
+# Launch driver startup
+@pytest.mark.launch_test
+@launch_testing.markers.keep_alive
+def generate_test_description():
+ return launch.LaunchDescription(
+ [
+ IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ [
+ get_package_share_directory("kuka_iiqka_eac_driver"),
+ "/launch/",
+ "startup.launch.py",
+ ]
+ )
+ ),
+ launch.actions.TimerAction(
+ period=2.0,
+ actions=[
+ launch.actions.ExecuteProcess(
+ cmd=["ros2", "lifecycle", "set", "robot_manager", "configure"],
+ output="screen",
+ ),
+ ],
+ ),
+ launch.actions.TimerAction(
+ period=4.0,
+ actions=[
+ launch.actions.ExecuteProcess(
+ cmd=["ros2", "lifecycle", "set", "robot_manager", "activate"],
+ output="screen",
+ ),
+ ],
+ ),
+ launch_testing.actions.ReadyToTest(),
+ ]
+ )
+
+
+class TestDriverActivation(unittest.TestCase):
+ def test_read_stdout(self, proc_output):
+ # Check for successful initialization
+ proc_output.assertWaitFor("got segment base", timeout=5)
+ proc_output.assertWaitFor(
+ "Successful initialization of hardware 'lbr_iisy3_r760'", timeout=5
+ )
+ # Check whether disabling automatic activation was successful
+ proc_output.assertWaitFor("Hardware Component with name '' does not exists", timeout=5)
+ # Check for successful configuration and activation
+ proc_output.assertWaitFor(
+ "Successful 'configure' of hardware 'lbr_iisy3_r760'", timeout=10
+ )
+ proc_output.assertWaitFor("Successful 'activate' of hardware 'lbr_iisy3_r760'", timeout=15)
diff --git a/kuka_iiqka_eac_driver/test/test_driver_startup.py b/kuka_iiqka_eac_driver/test/test_driver_startup.py
index 7c408732..c93dea6c 100644
--- a/kuka_iiqka_eac_driver/test/test_driver_startup.py
+++ b/kuka_iiqka_eac_driver/test/test_driver_startup.py
@@ -47,7 +47,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestDriverStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment base", timeout=5)
diff --git a/kuka_iiqka_eac_driver/test/test_multi_robot_startup.py b/kuka_iiqka_eac_driver/test/test_multi_robot_startup.py
index 53b08572..66857010 100644
--- a/kuka_iiqka_eac_driver/test/test_multi_robot_startup.py
+++ b/kuka_iiqka_eac_driver/test/test_multi_robot_startup.py
@@ -72,7 +72,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestMultiStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment test1_base", timeout=20)
diff --git a/kuka_kss_rsi_driver/CMakeLists.txt b/kuka_kss_rsi_driver/CMakeLists.txt
index c6a31f69..20b2fd91 100644
--- a/kuka_kss_rsi_driver/CMakeLists.txt
+++ b/kuka_kss_rsi_driver/CMakeLists.txt
@@ -57,6 +57,7 @@ install(TARGETS ${PROJECT_NAME} robot_manager_node
if(BUILD_TESTING)
find_package(launch_testing_ament_cmake)
add_launch_test(test/test_driver_startup.py)
+ add_launch_test(test/test_driver_activation.py)
add_launch_test(test/test_multi_robot_startup.py)
endif()
diff --git a/kuka_kss_rsi_driver/krl/ros_rsi.src b/kuka_kss_rsi_driver/krl/ros_rsi.src
index 3b7eaf29..cba641ea 100644
--- a/kuka_kss_rsi_driver/krl/ros_rsi.src
+++ b/kuka_kss_rsi_driver/krl/ros_rsi.src
@@ -65,6 +65,8 @@ DECL INT CONTID ; ContainerID
;ENDFOLD (USER INI)
;ENDFOLD (INI)
+PTP {A1 0, A2 -90, A3 90, A4 0, A5 0, A6 0}
+
; Create RSI Context
ret = RSI_CREATE("ros_rsi",CONTID,TRUE)
IF (ret <> RSIOK) THEN
diff --git a/kuka_kss_rsi_driver/package.xml b/kuka_kss_rsi_driver/package.xml
index 6879c837..4b4b1385 100644
--- a/kuka_kss_rsi_driver/package.xml
+++ b/kuka_kss_rsi_driver/package.xml
@@ -24,6 +24,9 @@
ros2_control
ros2_controllers
+ kuka_rsi_simulator
+ ros2lifecycle
+
ament_cmake
diff --git a/kuka_kss_rsi_driver/test/test_driver_activation.py b/kuka_kss_rsi_driver/test/test_driver_activation.py
new file mode 100644
index 00000000..4b780eed
--- /dev/null
+++ b/kuka_kss_rsi_driver/test/test_driver_activation.py
@@ -0,0 +1,88 @@
+# Copyright 2024 Áron Svastits
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+import launch
+import launch.actions
+import launch_testing.actions
+import launch_testing.markers
+import pytest
+
+from launch.launch_description_sources.python_launch_description_source import (
+ PythonLaunchDescriptionSource,
+)
+from launch.actions.include_launch_description import IncludeLaunchDescription
+from ament_index_python.packages import get_package_share_directory
+
+
+# Launch driver startup
+@pytest.mark.launch_test
+@launch_testing.markers.keep_alive
+def generate_test_description():
+ return launch.LaunchDescription(
+ [
+ IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ [
+ get_package_share_directory("kuka_kss_rsi_driver"),
+ "/launch/",
+ "startup.launch.py",
+ ]
+ )
+ ),
+ IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ [
+ get_package_share_directory("kuka_rsi_simulator"),
+ "/launch/",
+ "kuka_rsi_simulator.launch.py",
+ ]
+ )
+ ),
+ launch.actions.TimerAction(
+ period=2.0,
+ actions=[
+ launch.actions.ExecuteProcess(
+ cmd=["ros2", "lifecycle", "set", "robot_manager", "configure"],
+ output="screen",
+ ),
+ ],
+ ),
+ launch.actions.TimerAction(
+ period=4.0,
+ actions=[
+ launch.actions.ExecuteProcess(
+ cmd=["ros2", "lifecycle", "set", "robot_manager", "activate"],
+ output="screen",
+ ),
+ ],
+ ),
+ launch_testing.actions.ReadyToTest(),
+ ]
+ )
+
+
+class TestDriverActivation(unittest.TestCase):
+ def test_read_stdout(self, proc_output):
+ # Check for successful initialization
+ proc_output.assertWaitFor("got segment base", timeout=5)
+ proc_output.assertWaitFor(
+ "Successful initialization of hardware 'kr6_r700_sixx'", timeout=5
+ )
+ # Check whether disabling automatic activation was successful
+ proc_output.assertWaitFor("Hardware Component with name '' does not exists", timeout=5)
+ # Check for successful configuration and activation
+ proc_output.assertWaitFor("Successful 'configure' of hardware 'kr6_r700_sixx'", timeout=10)
+ proc_output.assertWaitFor("Successful 'activate' of hardware 'kr6_r700_sixx'", timeout=15)
diff --git a/kuka_kss_rsi_driver/test/test_driver_startup.py b/kuka_kss_rsi_driver/test/test_driver_startup.py
index ee80dddc..e8e11752 100644
--- a/kuka_kss_rsi_driver/test/test_driver_startup.py
+++ b/kuka_kss_rsi_driver/test/test_driver_startup.py
@@ -47,7 +47,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestDriverStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment base", timeout=5)
diff --git a/kuka_kss_rsi_driver/test/test_multi_robot_startup.py b/kuka_kss_rsi_driver/test/test_multi_robot_startup.py
index 42c8fbe3..589bc843 100644
--- a/kuka_kss_rsi_driver/test/test_multi_robot_startup.py
+++ b/kuka_kss_rsi_driver/test/test_multi_robot_startup.py
@@ -68,7 +68,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestMultiStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment test1_base", timeout=20)
diff --git a/kuka_sunrise_fri_driver/package.xml b/kuka_sunrise_fri_driver/package.xml
index 2c032a9f..eb74f19d 100644
--- a/kuka_sunrise_fri_driver/package.xml
+++ b/kuka_sunrise_fri_driver/package.xml
@@ -22,9 +22,10 @@
hardware_interface
controller_manager_msgs
- rosidl_default_runtime
ros2_control
ros2_controllers
+ fri_state_broadcaster
+ fri_configuration_controller
ament_cmake
diff --git a/kuka_sunrise_fri_driver/test/test_driver_startup.py b/kuka_sunrise_fri_driver/test/test_driver_startup.py
index 9e2b5c18..583faa20 100644
--- a/kuka_sunrise_fri_driver/test/test_driver_startup.py
+++ b/kuka_sunrise_fri_driver/test/test_driver_startup.py
@@ -47,7 +47,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestDriverStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment base", timeout=5)
diff --git a/kuka_sunrise_fri_driver/test/test_multi_robot_startup.py b/kuka_sunrise_fri_driver/test/test_multi_robot_startup.py
index 7519fb72..494ac910 100644
--- a/kuka_sunrise_fri_driver/test/test_multi_robot_startup.py
+++ b/kuka_sunrise_fri_driver/test/test_multi_robot_startup.py
@@ -68,7 +68,7 @@ def generate_test_description():
)
-class TestModels(unittest.TestCase):
+class TestMultiStartup(unittest.TestCase):
def test_read_stdout(self, proc_output):
# Check for successful initialization
proc_output.assertWaitFor("got segment test1_base", timeout=20)