Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate kuka-external-control-sdk #144

Merged
merged 92 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
29dc520
use client lib in hwif-without control mode switch
VX792 Jan 29, 2024
dc448ae
Merge branch 'master' into feature/client-sdk-integration
Feb 14, 2024
da10b61
add control mode change
Feb 14, 2024
2057b2c
add event subscriber to manager
Feb 14, 2024
07cb9d1
change type
Feb 14, 2024
4c62501
format
Feb 14, 2024
cd9acb7
add enums
Feb 14, 2024
e33e366
hack for LD_LIBRARY_PATH
Feb 14, 2024
0681361
fake hw in activation test
Feb 14, 2024
95e6891
set server event
Feb 14, 2024
d421a63
recv timeout
Feb 14, 2024
82ca89b
clean up
Feb 14, 2024
72588e6
Merge branch 'master' into feature/client-sdk-integration
Svastits Feb 14, 2024
0a9a31a
fix control mode changes
Feb 15, 2024
5da1665
log fix
Feb 15, 2024
ada4329
log
Feb 15, 2024
60d2b67
rollback launch
Feb 15, 2024
26675f5
modify access rights
Feb 15, 2024
5520057
format
Feb 15, 2024
a2d1baa
recv timeout
Feb 16, 2024
4102a5b
prev_control_mode type
Feb 16, 2024
4b1011c
fix build
Feb 16, 2024
88f47e8
mutex
Feb 16, 2024
52bb6a3
cleanup
Feb 16, 2024
38f7d5b
package xml update + ci
Feb 16, 2024
013c7d7
sudo mkdir
Feb 16, 2024
3ee0526
fix
Feb 16, 2024
c482233
git
Feb 16, 2024
58914f4
pipe fix
Feb 16, 2024
1b50a32
sudo
Feb 16, 2024
c140deb
home
Feb 16, 2024
123f144
fix dir
Feb 16, 2024
b154233
update name
Feb 16, 2024
1a88dc0
fix dir structure
Feb 16, 2024
0169a81
fix dir
Feb 16, 2024
031d366
update env
Feb 16, 2024
1688283
fix deactivate
Feb 16, 2024
16e558a
find_lib
Feb 16, 2024
ce584d3
fix build
Feb 16, 2024
344d634
debug
Feb 16, 2024
a80ab26
try without path
Feb 16, 2024
0fad5ea
Revert "try without path"
Feb 16, 2024
5c98cad
fix multiple deact
Feb 16, 2024
21a3d71
cleanup
Feb 16, 2024
dc12024
fix controller configuration
Feb 16, 2024
ddaf6a2
update build instructions
Feb 19, 2024
972ccc4
fix
Feb 19, 2024
1c1d664
remove unnecessary copy
Feb 19, 2024
d094985
fix switch
Feb 21, 2024
ca378d3
Merge branch 'feature/client-sdk-integration' of https://github.com/k…
Feb 21, 2024
19c06c5
package xml
Feb 22, 2024
84d9924
Merge remote-tracking branch 'origin/feature/client-sdk-integration' …
Feb 22, 2024
fb688ac
install deps
Feb 23, 2024
a41cd85
format
Feb 23, 2024
ac6861a
try pre-build script
Feb 23, 2024
b731c6b
remove sdk dep
Feb 23, 2024
ff2beb9
fix upstream
Feb 23, 2024
f456876
sudo
Feb 23, 2024
baa677a
clean up control mode handling
Feb 23, 2024
9af1556
fix before_build
Feb 23, 2024
ca5b320
try path fix
Feb 23, 2024
b4d0592
before init
Feb 23, 2024
c95dd23
install deps
Feb 23, 2024
f0cdacd
fix install path
Feb 23, 2024
6a102eb
protobuf dep
Feb 23, 2024
74e297c
fix dep
Feb 23, 2024
b9d8d4b
fix condition
Feb 23, 2024
fd8ec01
target include
Feb 23, 2024
d76dcc8
fix hack
Feb 23, 2024
a974c29
remove activation test
Feb 23, 2024
4df484a
spell
Feb 23, 2024
a924ae2
fix tests with new config
Feb 23, 2024
cc8b29f
extend ld_lib_path
Feb 23, 2024
6ef38d0
fix
Feb 23, 2024
d7db184
syntax
Feb 23, 2024
9a00b07
try extend again
Feb 23, 2024
35d83a8
fix hack
Feb 23, 2024
3e59d66
fix hack
Feb 23, 2024
b78026a
debug
Feb 23, 2024
4758447
debug2
Feb 23, 2024
7cddbe3
Update industrial_ci.yml
Svastits Feb 23, 2024
ad7f7db
Remove after init
Svastits Feb 23, 2024
b1c7d61
debug
Feb 26, 2024
c151645
fix env
Feb 26, 2024
9f698f7
cleanup
Feb 26, 2024
159934a
better driver init
Feb 26, 2024
0c2aac3
extend doc with torque difference
Feb 26, 2024
9a3b0a8
remove mock from doc
Feb 26, 2024
a53fdfe
cleanup
Feb 26, 2024
978bd66
fix log
Feb 28, 2024
4c9dc07
spell
Feb 28, 2024
223744e
typo
Feb 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/industrial_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ jobs:
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ matrix.env.ROS_DISTRO }}-${{ matrix.env.ROS_REPO }}

# Install and build kuka-external-control-sdk
- name: Install dependencies
run: sudo apt install -y cmake build-essential pkg-config libssl-dev protobuf-compiler-grpc libgrpc++-dev
- name: Clone sdk lib
run: git clone https://github.com/kroshu/kuka-external-control-sdk.git
working-directory: /home/runner/work
- name: Create build directory
run: mkdir -p /home/runner/work/kuka-external-control-sdk/kuka-external-control-sdk/build
- name: Build and install sdk
run: cmake .. && sudo make install
working-directory: /home/runner/work/kuka-external-control-sdk/kuka-external-control-sdk/build

# Run industrial_ci
- name: Extend LD_LIBRARY_PATH
run: echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib" >> $GITHUB_ENV
- name: Debug
run: ls -l /usr/local/lib && ls -l /usr/include/kuka/external-control-sdk/iiqka/ && echo $LD_LIBRARY_PATH

- uses: 'kroshu/industrial_ci@master'
env: ${{ matrix.env }}
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ sudo apt upgrade
rosdep install --from-paths . --ignore-src --rosdistro $ROS_DISTRO -y
```

Clone and build kuka-external-control-sdk in a different workspace.
- This library is necessary for the iiQKA ExternalAPI.Control driver
- The library is not a ROS2 package, therefore a different workspace is necessary, otherwise colcon will fail to build it
```bash
mkdir -p ~/sdk_ws/src
cd ~/sdk_ws/src
git clone https://github.com/kroshu/kuka-external-control-sdk.git
mkdir -p ~/sdk_ws/src/kuka-external-control-sdk/kuka-external-control-sdk/build
cd ~/sdk_ws/src/kuka-external-control-sdk/kuka-external-control-sdk/build
cmake ..
sudo make install
```

Build KUKA packages.
```bash
cd ~/ros2_ws
Expand Down
35 changes: 35 additions & 0 deletions kuka_drivers_core/include/kuka_drivers_core/hardware_event.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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.

#ifndef KUKA_DRIVERS_CORE__HARDWARE_EVENT_HPP_
#define KUKA_DRIVERS_CORE__HARDWARE_EVENT_HPP_

namespace kuka_drivers_core
{
/**
* @brief Enum for controller-side events
*/
enum class HardwareEvent : std::uint8_t
{
HARDWARE_EVENT_UNSPECIFIED = 0,
COMMAND_ACCEPTED = 2,
CONTROL_STARTED = 3,
CONTROL_STOPPED = 4,
CONTROL_MODE_SWITCH = 5,
ERROR = 6
};

} // namespace kuka_drivers_core

#endif // KUKA_DRIVERS_CORE__HARDWARE_EVENT_HPP_
49 changes: 7 additions & 42 deletions kuka_iiqka_eac_driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ endif()
# TODO: find better solution
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--copy-dt-needed-entries")

set(MOCK_KUKA_LIBS TRUE)

find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
Expand All @@ -29,47 +28,10 @@ find_package(kuka_drivers_core REQUIRED)
find_package(hardware_interface REQUIRED)
find_package(pluginlib REQUIRED)
find_package(controller_manager_msgs REQUIRED)
find_package(yaml-cpp REQUIRED)

include_directories(include)

if(NOT MOCK_KUKA_LIBS)
find_package(os-core-udp-communication REQUIRED)
find_package(motion-services-ecs-proto-api-cpp REQUIRED)
find_package(motion-external-proto-api-nanopb REQUIRED)
find_package(motion-services-ecs-proto-api-nanopb REQUIRED)
find_package(nanopb-helpers REQUIRED)
message("Using real kuka libs")
add_definitions(-DNON_MOCK_SETUP)
else()
find_package(Protobuf)
include_directories(include/mock)
add_library(os-core-udp-communication SHARED
src/mock/os-core-udp-communication/udp_replier_mock.cpp
src/mock/os-core-udp-communication/udp_socket_mock.cpp)
add_library(kuka::os-core-udp-communication ALIAS os-core-udp-communication)
install(TARGETS os-core-udp-communication
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

add_library(nanopb-helpers INTERFACE)
target_include_directories(nanopb-helpers INTERFACE include/mock/nanopb-helpers)
target_link_libraries(nanopb-helpers INTERFACE protobuf::libprotobuf)
add_library(kuka::nanopb-helpers ALIAS nanopb-helpers)

add_library(motion-services-ecs-proto-api-cpp INTERFACE)
target_include_directories(motion-services-ecs-proto-api-cpp INTERFACE include/mock/kuka)

add_library(motion-external-proto-api-nanopb INTERFACE)
target_include_directories(motion-external-proto-api-nanopb INTERFACE include/mock/nanopb/kuka/motion/external)
target_link_libraries(motion-external-proto-api-nanopb INTERFACE protobuf::libprotobuf)

add_library(motion-services-ecs-proto-api-nanopb INTERFACE)
target_include_directories(motion-services-ecs-proto-api-nanopb INTERFACE include/mock/nanopb/kuka/ecs/v1)
target_link_libraries(motion-external-proto-api-nanopb INTERFACE motion-external-proto-api-nanopb)
message("Using mock kuka libs")
remove_definitions(-DNON_MOCK_SETUP)
endif()
find_library(NAMES kuka-external-control-sdk PATHS "/usr/local/lib" REQUIRED)

add_library(${PROJECT_NAME} SHARED
src/hardware_interface.cpp
Expand All @@ -80,14 +42,13 @@ add_library(${PROJECT_NAME} SHARED
target_compile_definitions(${PROJECT_NAME} PRIVATE "KUKA_IIQKA_EAC_DRIVER_BUILDING_LIBRARY")

ament_target_dependencies(${PROJECT_NAME} rclcpp sensor_msgs hardware_interface kuka_drivers_core)
target_link_libraries(${PROJECT_NAME} motion-external-proto-api-nanopb motion-services-ecs-proto-api-cpp
motion-services-ecs-proto-api-nanopb yaml-cpp kuka::os-core-udp-communication kuka::nanopb-helpers)
target_link_libraries(${PROJECT_NAME} kuka-external-control-sdk)


add_executable(robot_manager_node
src/robot_manager_node.cpp)
ament_target_dependencies(robot_manager_node rclcpp kuka_drivers_core sensor_msgs controller_manager_msgs)
target_link_libraries(robot_manager_node kuka_drivers_core::communication_helpers motion-services-ecs-proto-api-cpp)
target_link_libraries(robot_manager_node kuka_drivers_core::communication_helpers kuka-external-control-sdk)

pluginlib_export_plugin_description_file(hardware_interface hardware_interface.xml)

Expand All @@ -108,4 +69,8 @@ ament_export_libraries(
${PROJECT_NAME}
)

# Hack to extend $LD_LIBRARY_PATH with /usr/local/lib when sourcing
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/ament_cmake_environment_hooks/library_path.dsv
"prepend-non-duplicate;LD_LIBRARY_PATH;/usr/local/lib")

ament_package()
2 changes: 2 additions & 0 deletions kuka_iiqka_eac_driver/config/ros2_controller_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ controller_manager:
type: effort_controllers/JointGroupPositionController
control_mode_handler:
type: kuka_controllers/ControlModeHandler
event_broadcaster:
type: kuka_controllers/EventBroadcaster

configure_components_on_start: [""]
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2024 Márk Szitanics
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_
#define KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_

#include "rclcpp/macros.hpp"

#include "kuka/external-control-sdk/common/irobot.h"
#include "kuka_drivers_core/hardware_event.hpp"
#include "kuka_iiqka_eac_driver/hardware_interface.hpp"

namespace kuka_eac
{
class KukaEACEventObserver : public kuka::external::control::EventHandler
{
public:
KukaEACEventObserver(KukaEACHardwareInterface * hw_interface) : hw_interface_(hw_interface) {}
void OnSampling() override
{
hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_STARTED);
RCLCPP_INFO(rclcpp::get_logger("KukaEACHardwareInterface"), "External control is active");
}
void OnControlModeSwitch(const std::string &) override
{
hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_MODE_SWITCH);
RCLCPP_INFO(
rclcpp::get_logger("KukaEACHardwareInterface"), "Control mode switch is in progress");
}
void OnStopped(const std::string &) override
{
hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::CONTROL_STOPPED);
RCLCPP_INFO(rclcpp::get_logger("KukaEACHardwareInterface"), "External control finished");
hw_interface_->set_stop_flag();
}
void OnError(const std::string & reason) override
{
hw_interface_->set_server_event(kuka_drivers_core::HardwareEvent::ERROR);
RCLCPP_ERROR(
rclcpp::get_logger("KukaEACHardwareInterface"), "External control stopped by an error");
RCLCPP_ERROR(rclcpp::get_logger("KukaEACHardwareInterface"), reason.c_str());
hw_interface_->set_stop_flag();
}

private:
KukaEACHardwareInterface * hw_interface_;
};

} // namespace kuka_eac

#endif // KUKA_IIQKA_EAC_DRIVER__EVENT_OBSERVER_HPP_
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@
#include "pluginlib/class_list_macros.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/rclcpp.hpp"

#include "kuka/external-control-sdk/iiqka/message_builder.h"
#include "kuka/external-control-sdk/iiqka/robot.h"
#include "rclcpp_lifecycle/state.hpp"

#include "kuka/ecs/v1/motion_services_ecs.grpc.pb.h"
#include "nanopb/kuka/core/motion/joint.pb.hh"
#include "nanopb/kuka/ecs/v1/control_signal_external.pb.hh"
#include "nanopb/kuka/ecs/v1/motion_state_external.pb.hh"
#include "os-core-udp-communication/replier.h"
#include "kuka_drivers_core/hardware_event.hpp"

#include "kuka_iiqka_eac_driver/visibility_control.h"

Expand All @@ -42,7 +41,6 @@ using CallbackReturn = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface

namespace kuka_eac
{

class KukaEACHardwareInterface : public hardware_interface::SystemInterface
{
public:
Expand Down Expand Up @@ -72,39 +70,35 @@ class KukaEACHardwareInterface : public hardware_interface::SystemInterface
KUKA_IIQKA_EAC_DRIVER_PUBLIC return_type
write(const rclcpp::Time & time, const rclcpp::Duration & period) override;

KUKA_IIQKA_EAC_DRIVER_PUBLIC void set_server_event(kuka_drivers_core::HardwareEvent event);

KUKA_IIQKA_EAC_DRIVER_PUBLIC void set_stop_flag() { stop_requested_ = true; };

private:
KUKA_IIQKA_EAC_DRIVER_LOCAL void ObserveControl();
KUKA_IIQKA_EAC_DRIVER_LOCAL bool SetupRobot();
KUKA_IIQKA_EAC_DRIVER_LOCAL bool SetupQoS();

bool is_active_ = false;
bool msg_received_ = false;
std::unique_ptr<kuka::external::control::iiqka::Robot> robot_ptr_;

std::vector<double> hw_position_commands_;
std::vector<double> hw_torque_commands_;
std::vector<double> hw_stiffness_commands_;
std::vector<double> hw_damping_commands_;

std::vector<double> hw_position_states_;
std::vector<double> hw_torque_states_;

double hw_control_mode_command_;

#ifdef NON_MOCK_SETUP
kuka::ecs::v1::CommandState command_state_;
std::unique_ptr<kuka::ecs::v1::ExternalControlService::Stub> stub_;
std::unique_ptr<grpc::ClientContext> context_;
#endif

std::thread observe_thread_;
double hw_control_mode_command_ = 0;
double server_state_ = 0;

std::unique_ptr<os::core::udp::communication::Replier> udp_replier_;
std::chrono::milliseconds receive_timeout_{100};
std::mutex event_mutex_;

uint8_t out_buff_arr_[1500];
kuka_drivers_core::ControlMode prev_control_mode_ =
kuka_drivers_core::ControlMode::CONTROL_MODE_UNSPECIFIED;
kuka_drivers_core::HardwareEvent last_event_ =
kuka_drivers_core::HardwareEvent::HARDWARE_EVENT_UNSPECIFIED;

nanopb::kuka::ecs::v1::ControlSignalExternal control_signal_ext_{
nanopb::kuka::ecs::v1::ControlSignalExternal_init_default};
nanopb::kuka::ecs::v1::MotionStateExternal motion_state_external_{
nanopb::kuka::ecs::v1::MotionStateExternal_init_default};
bool msg_received_;
std::atomic<bool> stop_requested_{false};
};
} // namespace kuka_eac

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,17 @@
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/bool.hpp"
#include "std_msgs/msg/u_int32.hpp"
#include "std_msgs/msg/u_int8.hpp"

#include "kuka_drivers_core/controller_handler.hpp"
#include "kuka_drivers_core/ros2_base_lc_node.hpp"

#include "kuka/ecs/v1/motion_services_ecs.grpc.pb.h"

namespace kuka_eac
{
class RobotManagerNode : public kuka_drivers_core::ROS2BaseLCNode
{
public:
RobotManagerNode();
~RobotManagerNode();

rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_configure(
const rclcpp_lifecycle::State &) override;
Expand All @@ -53,7 +51,7 @@ class RobotManagerNode : public kuka_drivers_core::ROS2BaseLCNode
const rclcpp_lifecycle::State &) override;

private:
void ObserveControl();
void EventSubscriptionCallback(const std_msgs::msg::UInt8::SharedPtr msg);
bool onControlModeChangeRequest(int control_mode);
bool onRobotModelChangeRequest(const std::string & robot_model);

Expand All @@ -62,32 +60,23 @@ class RobotManagerNode : public kuka_drivers_core::ROS2BaseLCNode
rclcpp::Client<controller_manager_msgs::srv::SwitchController>::SharedPtr
change_controller_state_client_;
rclcpp::CallbackGroup::SharedPtr cbg_;
rclcpp::CallbackGroup::SharedPtr event_cbg_;
std::string robot_model_;

kuka_drivers_core::ControllerHandler controller_handler_;

std::thread observe_thread_;
std::atomic<bool> terminate_{false};
bool param_declared_ = false;
#ifdef NON_MOCK_SETUP
std::unique_ptr<kuka::ecs::v1::ExternalControlService::Stub> stub_;
std::unique_ptr<grpc::ClientContext> context_;

std::condition_variable control_mode_cv_;
std::mutex control_mode_cv_m_;
bool control_mode_change_finished_;
#endif

rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr control_mode_pub_;

std::shared_ptr<rclcpp_lifecycle::LifecyclePublisher<std_msgs::msg::Bool>> is_configured_pub_;
rclcpp::Publisher<std_msgs::msg::Bool>::SharedPtr is_configured_pub_;
std_msgs::msg::Bool is_configured_msg_;

// There are two kinds of control modes with different number of necessary interfaces to be set:
// - in standard modes (position, torque), only the control signal to the used interface (1)
// - in impedance modes, the setpoint and the parameters describing the behaviour (2)
static constexpr int STANDARD_MODE_IF_SIZE = 1;
static constexpr int IMPEDANCE_MODE_IF_SIZE = 2;
rclcpp::Subscription<std_msgs::msg::UInt8>::SharedPtr event_subscriber_;
};

} // namespace kuka_eac
Expand Down
Loading
Loading