├── docs └── images │ └── abb_robots_people_ros.png ├── abb_egm_state_controller ├── config │ └── egm_state_controller.yaml ├── launch │ └── egm_state_controller.launch ├── egm_state_controller_plugin.xml ├── package.xml ├── LICENSE ├── README.md ├── CMakeLists.txt ├── include │ └── abb_egm_state_controller │ │ └── egm_state_controller.h └── src │ └── egm_state_controller.cpp ├── abb_egm_hardware_interface ├── config │ ├── egm_single_mech_unit_example.yaml │ ├── egm_yumi_mech_units_example.yaml │ ├── egm_multiple_mech_units_example.yaml │ └── base_configs_example.yaml ├── launch │ └── egm_hardware_interface.launch ├── package.xml ├── LICENSE ├── src │ ├── egm_controller_stopper_main.cpp │ ├── egm_hardware_interface_main.cpp │ └── egm_controller_stopper.cpp ├── include │ └── abb_egm_hardware_interface │ │ ├── egm_state_interface.h │ │ ├── egm_controller_stopper.h │ │ └── egm_hardware_interface.h ├── README.md └── CMakeLists.txt ├── abb_robot_bringup_examples ├── config │ ├── rosconsole.conf │ ├── ex2_controllers.yaml │ ├── ex2_hardware_base.yaml │ ├── ex3_hardware_base.yaml │ ├── ex2_hardware_egm.yaml │ ├── ex3_controllers.yaml │ └── ex3_hardware_egm.yaml ├── package.xml ├── launch │ ├── ex1_rws_only.launch │ ├── ex2_rws_and_egm_6axis_robot.launch │ └── ex3_rws_and_egm_yumi_robot.launch ├── LICENSE ├── CMakeLists.txt └── README.md ├── pkgs.repos ├── pkgs_only_sources.repos ├── abb_rws_state_publisher ├── package.xml ├── launch │ └── rws_state_publisher.launch ├── LICENSE ├── src │ ├── main.cpp │ └── rws_state_publisher.cpp ├── README.md ├── CMakeLists.txt └── include │ └── abb_rws_state_publisher │ └── rws_state_publisher.h ├── abb_robot_cpp_utilities ├── package.xml ├── LICENSE ├── README.md ├── include │ └── abb_robot_cpp_utilities │ │ ├── initialization.h │ │ ├── verification.h │ │ ├── parameters.h │ │ └── mapping.h ├── src │ ├── verification.cpp │ ├── initialization.cpp │ └── parameters.cpp └── CMakeLists.txt ├── abb_rws_service_provider ├── package.xml ├── launch │ └── rws_service_provider.launch ├── LICENSE ├── src │ └── main.cpp ├── README.md └── CMakeLists.txt ├── LICENSE ├── .github └── workflows │ ├── ci_bionic.yml │ └── ci_focal.yml └── README.md /docs/images/abb_robots_people_ros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ros-industrial/abb_robot_driver/HEAD/docs/images/abb_robots_people_ros.png -------------------------------------------------------------------------------- /abb_egm_state_controller/config/egm_state_controller.yaml: -------------------------------------------------------------------------------- 1 | egm_state_controller: 2 | type : abb_egm_state_controller/EGMStateController 3 | publish_rate : 250 4 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/config/egm_single_mech_unit_example.yaml: -------------------------------------------------------------------------------- 1 | # These settings must match: 2 | # - Port numbers specified in the ABB robot controller's system configurations for EGM communication. 3 | egm: 4 | channel_1: 5 | port_number: 6511 6 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/rosconsole.conf: -------------------------------------------------------------------------------- 1 | log4j.logger.ros.abb_egm_hardware_interface=DEBUG 2 | log4j.logger.ros.abb_robot_cpp_utilities=DEBUG 3 | log4j.logger.ros.abb_rws_service_provider=DEBUG 4 | log4j.logger.ros.abb_rws_state_publisher=DEBUG 5 | -------------------------------------------------------------------------------- /abb_egm_state_controller/launch/egm_state_controller.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/config/egm_yumi_mech_units_example.yaml: -------------------------------------------------------------------------------- 1 | # These settings must match: 2 | # - Port numbers specified in the ABB robot controller's system configurations for EGM communication. 3 | # - Names of the mechanical unit groups intended to be controlled by respective EGM communication channel. 4 | egm: 5 | channel_1: 6 | port_number: 6511 7 | mech_unit_group: "rob_l" 8 | channel_2: 9 | port_number: 6512 10 | mech_unit_group: "rob_r" 11 | -------------------------------------------------------------------------------- /pkgs.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | abb_libegm: 3 | type: git 4 | url: https://github.com/ros-industrial/abb_libegm.git 5 | version: e0b8c3b0 6 | abb_librws: 7 | type: git 8 | url: https://github.com/ros-industrial/abb_librws.git 9 | version: 3a5914ef 10 | abb_egm_rws_managers: 11 | type: git 12 | url: https://github.com/ros-industrial/abb_egm_rws_managers.git 13 | version: 7d69d3dd 14 | abb_robot_driver: 15 | type: git 16 | url: https://github.com/ros-industrial/abb_robot_driver.git 17 | version: master 18 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex2_controllers.yaml: -------------------------------------------------------------------------------- 1 | joint_state_controller: 2 | type: joint_state_controller/JointStateController 3 | publish_rate: 250 4 | 5 | egm_state_controller: 6 | type : abb_egm_state_controller/EGMStateController 7 | publish_rate : 250 8 | 9 | # These settings must match: 10 | # - Joint names extracted from the ABB robot controller. 11 | joint_group_velocity_controller: 12 | type: velocity_controllers/JointGroupVelocityController 13 | joints: 14 | - joint_1 15 | - joint_2 16 | - joint_3 17 | - joint_4 18 | - joint_5 19 | - joint_6 20 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/config/egm_multiple_mech_units_example.yaml: -------------------------------------------------------------------------------- 1 | # These settings must match: 2 | # - Port numbers specified in the ABB robot controller's system configurations for EGM communication. 3 | # - Names of the mechanical unit groups intended to be controlled by respective EGM communication channel. 4 | egm: 5 | channel_1: 6 | port_number: 6511 7 | mech_unit_group: "rob1" 8 | channel_2: 9 | port_number: 6512 10 | mech_unit_group: "rob2" 11 | channel_3: 12 | port_number: 6513 13 | mech_unit_group: "rob3" 14 | channel_4: 15 | port_number: 6514 16 | mech_unit_group: "rob4" 17 | -------------------------------------------------------------------------------- /abb_egm_state_controller/egm_state_controller_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The EGMStateController publishes the current state of Externally Guided Motion (EGM) communication channels 5 | that has been set up between an ABB robot controller and external EGM servers. 6 | 7 | The controller expects a hardware interface of the type EGMStateInterface. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/config/base_configs_example.yaml: -------------------------------------------------------------------------------- 1 | # Indicator for if it is ok to wait indefinitely for ROS services to become available. 2 | # 3 | # Note: This is only used during initialization. 4 | no_service_timeout: false 5 | 6 | # Lists of ros_control controllers, which are: 7 | # - Always ok to start (for example, when EGM is inactive). 8 | # - Ok to keep running (for example, when EGM becomes inactive). 9 | # 10 | # Note: These lists are intended for passive controllers, which doesn't control motion. 11 | ros_control: 12 | controllers: 13 | always_ok_to_start: ["egm_state_controller", "joint_state_controller"] 14 | ok_to_keep_running: ["egm_state_controller", "joint_state_controller"] 15 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex2_hardware_base.yaml: -------------------------------------------------------------------------------- 1 | # Indicator for if it is ok to wait indefinitely for ROS services to become available. 2 | # 3 | # Note: This is only used during initialization. 4 | no_service_timeout: false 5 | 6 | # Lists of ros_control controllers, which are: 7 | # - Always ok to start (for example, when EGM is inactive). 8 | # - Ok to keep running (for example, when EGM becomes inactive). 9 | # 10 | # Note: These lists are intended for passive controllers, which doesn't control motion. 11 | ros_control: 12 | controllers: 13 | always_ok_to_start: ["egm_state_controller", "joint_state_controller"] 14 | ok_to_keep_running: ["egm_state_controller", "joint_state_controller"] 15 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex3_hardware_base.yaml: -------------------------------------------------------------------------------- 1 | # Indicator for if it is ok to wait indefinitely for ROS services to become available. 2 | # 3 | # Note: This is only used during initialization. 4 | no_service_timeout: false 5 | 6 | # Lists of ros_control controllers, which are: 7 | # - Always ok to start (for example, when EGM is inactive). 8 | # - Ok to keep running (for example, when EGM becomes inactive). 9 | # 10 | # Note: These lists are intended for passive controllers, which doesn't control motion. 11 | ros_control: 12 | controllers: 13 | always_ok_to_start: ["egm_state_controller", "joint_state_controller"] 14 | ok_to_keep_running: ["egm_state_controller", "joint_state_controller"] 15 | -------------------------------------------------------------------------------- /pkgs_only_sources.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | abb_libegm: 3 | type: git 4 | url: https://github.com/ros-industrial/abb_libegm.git 5 | version: e0b8c3b0 6 | abb_librws: 7 | type: git 8 | url: https://github.com/ros-industrial/abb_librws.git 9 | version: 3a5914ef 10 | abb_egm_rws_managers: 11 | type: git 12 | url: https://github.com/ros-industrial/abb_egm_rws_managers.git 13 | version: 7d69d3dd 14 | abb_robot_driver: 15 | type: git 16 | url: https://github.com/ros-industrial/abb_robot_driver.git 17 | version: master 18 | abb_robot_driver_interfaces: 19 | type: git 20 | url: https://github.com/ros-industrial/abb_robot_driver_interfaces.git 21 | version: 0.5.3 22 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex2_hardware_egm.yaml: -------------------------------------------------------------------------------- 1 | # These settings must match: 2 | # - Port numbers specified in the ABB robot controller's system configurations for EGM communication. 3 | egm: 4 | channel_1: 5 | port_number: 6511 6 | 7 | # These settings must match: 8 | # - Joint names extracted from the ABB robot controller. 9 | # 10 | # Please see http://wiki.ros.org/joint_limits_interface for more details about joint limits. 11 | joint_limits: 12 | joint_1: 13 | has_velocity_limits: true 14 | max_velocity: 0.2 15 | joint_2: 16 | has_velocity_limits: true 17 | max_velocity: 0.2 18 | joint_3: 19 | has_velocity_limits: true 20 | max_velocity: 0.2 21 | joint_4: 22 | has_velocity_limits: true 23 | max_velocity: 0.2 24 | joint_5: 25 | has_velocity_limits: true 26 | max_velocity: 0.2 27 | joint_6: 28 | has_velocity_limits: true 29 | max_velocity: 0.2 30 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex3_controllers.yaml: -------------------------------------------------------------------------------- 1 | joint_state_controller: 2 | type: joint_state_controller/JointStateController 3 | publish_rate: 250 4 | 5 | egm_state_controller: 6 | type : abb_egm_state_controller/EGMStateController 7 | publish_rate : 250 8 | 9 | # These settings must match: 10 | # - Joint names extracted from the ABB robot controller. 11 | # - The 'yumi_' prefix must match the nickname/identifier, 12 | # which is set in the corresponding launch file. 13 | joint_group_velocity_controller: 14 | type: velocity_controllers/JointGroupVelocityController 15 | joints: 16 | - yumi_robl_joint_1 17 | - yumi_robl_joint_2 18 | - yumi_robl_joint_3 19 | - yumi_robl_joint_4 20 | - yumi_robl_joint_5 21 | - yumi_robl_joint_6 22 | - yumi_robl_joint_7 23 | - yumi_robr_joint_1 24 | - yumi_robr_joint_2 25 | - yumi_robr_joint_3 26 | - yumi_robr_joint_4 27 | - yumi_robr_joint_5 28 | - yumi_robr_joint_6 29 | - yumi_robr_joint_7 30 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_rws_state_publisher 5 | 0.5.0 6 | 7 | Provides a ROS node implementation that periodically publishes ROS messages, containing an 8 | ABB robot controller's current state collected via Robot Web Services (RWS) communication. 9 | 10 | G.A. vd. Hoorn (TU Delft Robotics Institute) 11 | BSD-3-Clause 12 | Jon Tjerngren 13 | 14 | catkin 15 | 16 | abb_egm_rws_managers 17 | abb_rapid_sm_addin_msgs 18 | abb_robot_cpp_utilities 19 | abb_robot_msgs 20 | roscpp 21 | sensor_msgs 22 | 23 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_robot_bringup_examples 5 | 0.5.0 6 | 7 | Provides some basic examples of how the ABB robot controller driver's components can be launched in ROS. 8 | 9 | G.A. vd. Hoorn (TU Delft Robotics Institute) 10 | BSD-3-Clause 11 | Jon Tjerngren 12 | 13 | catkin 14 | 15 | abb_egm_hardware_interface 16 | abb_egm_state_controller 17 | abb_rws_service_provider 18 | abb_rws_state_publisher 19 | controller_manager 20 | joint_state_controller 21 | velocity_controllers 22 | 23 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_robot_cpp_utilities 5 | 0.5.0 6 | 7 | Provides a C++ library with utility functions for the ABB robot controller driver's ROS packages. 8 | 9 | Utility functions can for example be: 10 | - Mapping between ROS messages, and robot controller messages. 11 | - Retrieval of mandatory and optional ROS parameters. 12 | 13 | G.A. vd. Hoorn (TU Delft Robotics Institute) 14 | BSD-3-Clause 15 | Jon Tjerngren 16 | 17 | catkin 18 | 19 | abb_egm_msgs 20 | abb_egm_rws_managers 21 | abb_rapid_msgs 22 | abb_rapid_sm_addin_msgs 23 | abb_robot_msgs 24 | roscpp 25 | 26 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/launch/egm_hardware_interface.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /abb_rws_service_provider/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_rws_service_provider 5 | 0.5.0 6 | 7 | Provides a ROS node implementation that exposes a set of ROS services, for sending requests to an 8 | ABB robot controller via Robot Web Services (RWS) communication. 9 | 10 | RWS requests can for example be: 11 | - Resetting the RAPID program pointer. 12 | - Starting/stopping the RAPID program. 13 | - Reading/writing IO-signals or RAPID variables. 14 | 15 | G.A. vd. Hoorn (TU Delft Robotics Institute) 16 | BSD-3-Clause 17 | Jon Tjerngren 18 | 19 | catkin 20 | 21 | abb_egm_rws_managers 22 | abb_rapid_sm_addin_msgs 23 | abb_robot_cpp_utilities 24 | abb_robot_msgs 25 | roscpp 26 | 27 | -------------------------------------------------------------------------------- /abb_rws_service_provider/launch/rws_service_provider.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/launch/ex1_rws_only.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /abb_egm_state_controller/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_egm_state_controller 5 | 0.5.0 6 | 7 | Provides an implementation for a ros_control-based controller interface, which publishes the current state of 8 | Externally Guided Motion (EGM) communication channels that has been set up between an ABB robot controller 9 | and external EGM servers. 10 | 11 | G.A. vd. Hoorn (TU Delft Robotics Institute) 12 | BSD-3-Clause 13 | Jon Tjerngren 14 | 15 | catkin 16 | 17 | abb_egm_hardware_interface 18 | abb_egm_msgs 19 | abb_robot_cpp_utilities 20 | controller_interface 21 | pluginlib 22 | realtime_tools 23 | roscpp 24 | 25 | controller_manager 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | abb_egm_hardware_interface 5 | 0.5.0 6 | 7 | Provides an implementation for a ros_control-based hardware interface, which facilitates communication 8 | with ABB robot controllers that supports the Externally Guided Motion (EGM) interface. 9 | 10 | A ROS node implementation is also provided for starting a ros_control controller manager, which drives a single 11 | instance of the EGM hardware interface toward an ABB robot controller. 12 | 13 | G.A. vd. Hoorn (TU Delft Robotics Institute) 14 | BSD-3-Clause 15 | Jon Tjerngren 16 | 17 | catkin 18 | 19 | abb_egm_rws_managers 20 | abb_robot_cpp_utilities 21 | abb_robot_msgs 22 | controller_manager 23 | controller_manager_msgs 24 | hardware_interface 25 | joint_limits_interface 26 | roscpp 27 | 28 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/launch/rws_state_publisher.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_egm_state_controller/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_rws_service_provider/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, ABB Schweiz AG 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with 5 | or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | * Redistributions in binary form must reproduce the 12 | above copyright notice, this list of conditions 13 | and the following disclaimer in the documentation 14 | and/or other materials provided with the 15 | distribution. 16 | * Neither the name of ABB nor the names of its 17 | contributors may be used to endorse or promote 18 | products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /.github/workflows/ci_bionic.yml: -------------------------------------------------------------------------------- 1 | name: CI - Ubuntu Bionic 2 | 3 | on: 4 | # direct pushes to protected branches are not supported 5 | pull_request: 6 | # run every day, at 6am UTC 7 | schedule: 8 | - cron: '0 6 * * *' 9 | # allow manually starting this workflow 10 | workflow_dispatch: 11 | 12 | jobs: 13 | industrial_ci: 14 | strategy: 15 | matrix: 16 | env: 17 | - {ROS_DISTRO: melodic, ROS_REPO: testing} 18 | - {ROS_DISTRO: melodic, ROS_REPO: main} 19 | name: ROS Melodic (${{ matrix.env.ROS_REPO }}) 20 | # industrial_ci uses Docker, so we don't need a specific Ubuntu version 21 | runs-on: ubuntu-latest 22 | env: 23 | CI_NAME: Ubuntu Bionic 24 | OS_NAME: ubuntu 25 | OS_CODE_NAME: bionic 26 | CCACHE_DIR: "/home/runner/work/abb_robot_driver/abb_robot_driver/bionic/.ccache" 27 | UPSTREAM_WORKSPACE: 'pkgs.repos -abb_robot_driver' 28 | steps: 29 | - uses: actions/checkout@v3 30 | 31 | - name: Prepare ccache timestamp 32 | id: ccache_cache_timestamp 33 | shell: cmake -P {0} 34 | run: | 35 | string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) 36 | message("::set-output name=timestamp::${current_date}") 37 | 38 | - name: ccache cache files 39 | uses: actions/cache@v3 40 | with: 41 | path: ${{ env.OS_CODE_NAME }}/.ccache 42 | key: ${{ env.OS_CODE_NAME }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} 43 | restore-keys: | 44 | ${{ env.OS_CODE_NAME }}-ccache- 45 | 46 | - uses: 'ros-industrial/industrial_ci@master' 47 | env: ${{matrix.env}} 48 | -------------------------------------------------------------------------------- /.github/workflows/ci_focal.yml: -------------------------------------------------------------------------------- 1 | name: CI - Ubuntu Focal 2 | 3 | on: 4 | # direct pushes to protected branches are not supported 5 | pull_request: 6 | # run every day, at 6am UTC 7 | schedule: 8 | - cron: '0 6 * * *' 9 | # allow manually starting this workflow 10 | workflow_dispatch: 11 | 12 | jobs: 13 | industrial_ci: 14 | strategy: 15 | matrix: 16 | env: 17 | - {ROS_DISTRO: noetic, ROS_REPO: testing} 18 | - {ROS_DISTRO: noetic, ROS_REPO: main} 19 | name: ROS Noetic (${{ matrix.env.ROS_REPO }}) 20 | # industrial_ci uses Docker, so we don't need a specific Ubuntu version 21 | runs-on: ubuntu-latest 22 | env: 23 | ADDITIONAL_DEBS: "python3-osrf-pycommon" 24 | BUILDER: catkin_tools 25 | CI_NAME: Ubuntu Focal 26 | OS_NAME: ubuntu 27 | OS_CODE_NAME: focal 28 | CCACHE_DIR: "/home/runner/work/abb_robot_driver/abb_robot_driver/focal/.ccache" 29 | UPSTREAM_WORKSPACE: 'pkgs.repos -abb_robot_driver' 30 | steps: 31 | - uses: actions/checkout@v3 32 | 33 | - name: Prepare ccache timestamp 34 | id: ccache_cache_timestamp 35 | shell: cmake -P {0} 36 | run: | 37 | string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC) 38 | message("::set-output name=timestamp::${current_date}") 39 | 40 | - name: ccache cache files 41 | uses: actions/cache@v3 42 | with: 43 | path: ${{ env.OS_CODE_NAME }}/.ccache 44 | key: ${{ env.OS_CODE_NAME }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} 45 | restore-keys: | 46 | ${{ env.OS_CODE_NAME }}-ccache- 47 | 48 | - uses: 'ros-industrial/industrial_ci@master' 49 | env: ${{matrix.env}} 50 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/config/ex3_hardware_egm.yaml: -------------------------------------------------------------------------------- 1 | # These settings must match: 2 | # - Port numbers specified in the ABB robot controller's system configurations for EGM communication. 3 | # - Names of the mechanical unit groups intended to be controlled by respective EGM communication channel. 4 | egm: 5 | channel_1: 6 | port_number: 6511 7 | mech_unit_group: "rob_l" 8 | channel_2: 9 | port_number: 6512 10 | mech_unit_group: "rob_r" 11 | 12 | # These settings must match: 13 | # - Joint names extracted from the ABB robot controller. 14 | # - The 'yumi_' prefix must match the nickname/identifier, 15 | # which is set in the corresponding launch file. 16 | # 17 | # See http://wiki.ros.org/joint_limits_interface for more info about available joint limits: 18 | joint_limits: 19 | yumi_robl_joint_1: 20 | has_velocity_limits: true 21 | max_velocity: 0.2 22 | yumi_robl_joint_2: 23 | has_velocity_limits: true 24 | max_velocity: 0.2 25 | yumi_robl_joint_3: 26 | has_velocity_limits: true 27 | max_velocity: 0.2 28 | yumi_robl_joint_4: 29 | has_velocity_limits: true 30 | max_velocity: 0.2 31 | yumi_robl_joint_5: 32 | has_velocity_limits: true 33 | max_velocity: 0.2 34 | yumi_robl_joint_6: 35 | has_velocity_limits: true 36 | max_velocity: 0.2 37 | yumi_robl_joint_7: 38 | has_velocity_limits: true 39 | max_velocity: 0.2 40 | yumi_robr_joint_1: 41 | has_velocity_limits: true 42 | max_velocity: 0.2 43 | yumi_robr_joint_2: 44 | has_velocity_limits: true 45 | max_velocity: 0.2 46 | yumi_robr_joint_3: 47 | has_velocity_limits: true 48 | max_velocity: 0.2 49 | yumi_robr_joint_4: 50 | has_velocity_limits: true 51 | max_velocity: 0.2 52 | yumi_robr_joint_5: 53 | has_velocity_limits: true 54 | max_velocity: 0.2 55 | yumi_robr_joint_6: 56 | has_velocity_limits: true 57 | max_velocity: 0.2 58 | yumi_robr_joint_7: 59 | has_velocity_limits: true 60 | max_velocity: 0.2 61 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/README.md: -------------------------------------------------------------------------------- 1 | # abb_robot_cpp_utilities 2 | 3 | [![license - bsd 3 clause](https://img.shields.io/:license-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 4 | [![support level: vendor](https://img.shields.io/badge/support%20level-vendor-brightgreen.svg)](http://rosindustrial.org/news/2016/10/7/better-supporting-a-growing-ros-industrial-software-platform) 5 | 6 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 7 | **The package is provided "as-is", and as such no more than limited support can be expected.** 8 | 9 | ## Overview 10 | 11 | The `abb_robot_cpp_utilities` package provides C++ utility functions for developing ROS nodes (*e.g. reading parameters from the ROS parameter server*). 12 | 13 | Please see [abb_robot_driver](https://github.com/ros-industrial/abb_robot_driver) for more details. 14 | 15 | ## Acknowledgements 16 | 17 | ### ROSIN Project 18 | 19 |

20 | 21 | rosin_logo 22 | 23 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 24 |

25 | eu_flag 26 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 27 |

28 | 29 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 30 | 31 | ### Special Thanks 32 | 33 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 34 | -------------------------------------------------------------------------------- /abb_egm_state_controller/README.md: -------------------------------------------------------------------------------- 1 | # abb_egm_state_controller 2 | 3 | [![license - bsd 3 clause](https://img.shields.io/:license-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 4 | [![support level: vendor](https://img.shields.io/badge/support%20level-vendor-brightgreen.svg)](http://rosindustrial.org/news/2016/10/7/better-supporting-a-growing-ros-industrial-software-platform) 5 | 6 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 7 | **The package is provided "as-is", and as such no more than limited support can be expected.** 8 | 9 | ## Overview 10 | 11 | The `abb_egm_state_controller` package provides a `ros_control`-based controller, which publishes the current state of *Externally Guided Motion* (`EGM`) communication channels into the ROS system. 12 | 13 | Please see [abb_robot_driver](https://github.com/ros-industrial/abb_robot_driver) for more details. 14 | 15 | ## Acknowledgements 16 | 17 | ### ROSIN Project 18 | 19 |

20 | 21 | rosin_logo 22 | 23 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 24 |

25 | eu_flag 26 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 27 |

28 | 29 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 30 | 31 | ### Special Thanks 32 | 33 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 34 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version}) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # Catkin packages 33 | #----------------------------- 34 | find_package(catkin REQUIRED) 35 | 36 | #=========================================================== 37 | # Catkin package specific configurations 38 | #=========================================================== 39 | catkin_package( 40 | CATKIN_DEPENDS 41 | abb_egm_hardware_interface 42 | abb_egm_state_controller 43 | abb_rws_service_provider 44 | abb_rws_state_publisher 45 | controller_manager 46 | joint_state_controller 47 | velocity_controllers 48 | ) 49 | 50 | #=========================================================== 51 | # Install 52 | #=========================================================== 53 | install( 54 | DIRECTORY config launch 55 | DESTINATION "${CATKIN_PACKAGE_SHARE_DESTINATION}" 56 | ) 57 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/include/abb_robot_cpp_utilities/initialization.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_ROBOT_CPP_UTILITIES_INITIALIZATION_H 38 | #define ABB_ROBOT_CPP_UTILITIES_INITIALIZATION_H 39 | 40 | #include 41 | 42 | namespace abb 43 | { 44 | namespace robot 45 | { 46 | namespace utilities 47 | { 48 | 49 | /** 50 | * \brief Attempts to establish a connection to a robot controller's RWS server. 51 | * 52 | * If a connection is established, then a structured description of the robot controller is returned. 53 | * 54 | * \param rws_manager for handling the RWS communication with the robot controller. 55 | * \param robot_controller_id for an identifier/nickname for the targeted robot controller. 56 | * \param no_connection_timeout indicator whether to wait indefinitely on the robot controller. 57 | * 58 | * \return RobotControllerDescription of the robot controller. 59 | * 60 | * \throw std::runtime_error if unable to establish a connection. 61 | */ 62 | RobotControllerDescription establishRWSConnection(RWSManager& rws_manager, 63 | const std::string& robot_controller_id, 64 | const bool no_connection_timeout); 65 | 66 | } 67 | } 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/launch/ex2_rws_and_egm_6axis_robot.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/launch/ex3_rws_and_egm_yumi_robot.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/src/main.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace 45 | { 46 | /** 47 | * \brief Name for ROS logging in the 'main' context. 48 | */ 49 | constexpr char ROS_LOG_MAIN[]{"main"}; 50 | } 51 | 52 | int main(int argc, char** argv) 53 | { 54 | //-------------------------------------------------------- 55 | // Preparations 56 | //-------------------------------------------------------- 57 | ros::init(argc, argv, "rws_state_publisher"); 58 | 59 | // Create a node handle, in the namespace where 60 | // the node should read parameters from. 61 | ros::NodeHandle nh_params{"~"}; 62 | 63 | // Create a node handle, in the namespace where 64 | // the node should publish messages in. 65 | // 66 | // Note: Using "rws" to indicate that the messages are 67 | // related to Robot Web Services (RWS) 68 | // communication. 69 | ros::NodeHandle nh_msgs{"rws"}; 70 | 71 | //-------------------------------------------------------- 72 | // Start node execution 73 | //-------------------------------------------------------- 74 | try 75 | { 76 | abb::robot::RWSStatePublisher rws_state_publisher{nh_params, nh_msgs}; 77 | ros::spin(); 78 | } 79 | catch(const std::runtime_error& exception) 80 | { 81 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Runtime error: '" << exception.what() << "'"); 82 | return EXIT_FAILURE; 83 | } 84 | catch(const std::exception& exception) 85 | { 86 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Exception '" << exception.what() << "'"); 87 | return EXIT_FAILURE; 88 | } 89 | catch(...) 90 | { 91 | ROS_FATAL_NAMED(ROS_LOG_MAIN, "Unknown exception"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | return EXIT_SUCCESS; 96 | } 97 | -------------------------------------------------------------------------------- /abb_rws_service_provider/src/main.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace 45 | { 46 | /** 47 | * \brief Name for ROS logging in the 'main' context. 48 | */ 49 | constexpr char ROS_LOG_MAIN[]{"main"}; 50 | } 51 | 52 | int main(int argc, char** argv) 53 | { 54 | //-------------------------------------------------------- 55 | // Preparations 56 | //-------------------------------------------------------- 57 | ros::init(argc, argv, "rws_service_provider"); 58 | 59 | // Create a node handle, in the namespace where 60 | // the node should read parameters from. 61 | ros::NodeHandle nh_params{"~"}; 62 | 63 | // Create a node handle, in the namespace where 64 | // the node should advertise services in. 65 | // 66 | // Note: Using "rws" to indicate that the services are 67 | // related to Robot Web Services (RWS) 68 | // communication. 69 | ros::NodeHandle nh_srvs{"rws"}; 70 | 71 | //-------------------------------------------------------- 72 | // Start node execution 73 | //-------------------------------------------------------- 74 | try 75 | { 76 | abb::robot::RWSServiceProvider rws_service_provider{nh_params, nh_srvs}; 77 | ros::spin(); 78 | } 79 | catch(const std::runtime_error& exception) 80 | { 81 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Runtime error: '" << exception.what() << "'"); 82 | return EXIT_FAILURE; 83 | } 84 | catch(const std::exception& exception) 85 | { 86 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Exception '" << exception.what() << "'"); 87 | return EXIT_FAILURE; 88 | } 89 | catch(...) 90 | { 91 | ROS_FATAL_NAMED(ROS_LOG_MAIN, "Unknown exception"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | return EXIT_SUCCESS; 96 | } 97 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/src/egm_controller_stopper_main.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace 45 | { 46 | /** 47 | * \brief Name for ROS logging in the 'main' context. 48 | */ 49 | constexpr char ROS_LOG_MAIN[]{"main"}; 50 | } 51 | 52 | int main(int argc, char** argv) 53 | { 54 | //-------------------------------------------------------- 55 | // Preparations 56 | //-------------------------------------------------------- 57 | ros::init(argc, argv, "egm_controller_stopper"); 58 | 59 | // Create a node handle, in the namespace where 60 | // the node should read parameters from. 61 | ros::NodeHandle nh_params{"~"}; 62 | 63 | // Create a node handle, in the namespace where 64 | // the node should subscribe to messages in. 65 | ros::NodeHandle nh_msgs{"egm"}; 66 | 67 | // Create a node handle, in the namespace where 68 | // the node should call services in. 69 | ros::NodeHandle nh_srvs{"egm/controller_manager"}; 70 | 71 | //-------------------------------------------------------- 72 | // Start node execution 73 | //-------------------------------------------------------- 74 | try 75 | { 76 | abb::robot::EGMControllerStopper egm_controller_stopper{nh_params, nh_msgs, nh_srvs}; 77 | ros::spin(); 78 | } 79 | catch(const std::runtime_error& exception) 80 | { 81 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Runtime error: '" << exception.what() << "'"); 82 | return EXIT_FAILURE; 83 | } 84 | catch(const std::exception& exception) 85 | { 86 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Exception '" << exception.what() << "'"); 87 | return EXIT_FAILURE; 88 | } 89 | catch(...) 90 | { 91 | ROS_FATAL_NAMED(ROS_LOG_MAIN, "Unknown exception"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | return EXIT_SUCCESS; 96 | } 97 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/include/abb_robot_cpp_utilities/verification.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_ROBOT_CPP_UTILITIES_VERIFICATION_H 38 | #define ABB_ROBOT_CPP_UTILITIES_VERIFICATION_H 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace abb 45 | { 46 | namespace robot 47 | { 48 | namespace utilities 49 | { 50 | 51 | /** 52 | * \brief Verifies that an IP address string represents a valid IP address. 53 | * 54 | * \param ip_address to verify. 55 | * 56 | * \throw std::runtime_error if the IP address is invalid. 57 | */ 58 | void verifyIPAddress(const std::string& ip_address); 59 | 60 | /** 61 | * \brief Verifies that a port number is valid, i.e. in the range [0, 65535]. 62 | * 63 | * \param port_number to verify. 64 | * 65 | * \throw std::runtime_error if the port number is invalid. 66 | */ 67 | void verifyPortNumber(const int port_number); 68 | 69 | /** 70 | * \brief Verifies that a rate [Hz] is valid, i.e. positive. 71 | * 72 | * \param rate to verify. 73 | * 74 | * \throw std::runtime_error if the rate is invalid. 75 | */ 76 | void verifyRate(const double rate); 77 | 78 | /** 79 | * \brief Verifies that the RobotWare version is supported. 80 | * 81 | * Note: For now, only RobotWare versions in the range [6.07.01, 7.0) are supported (i.e. excluding 7.0). 82 | * 83 | * \param rw_version to verify. 84 | * 85 | * \throw std::runtime_error if the RobotWare version is not supported. 86 | */ 87 | void verifyRobotWareVersion(const RobotWareVersion& rw_version); 88 | 89 | /** 90 | * \brief Verifies that the RobotWare StateMachine Add-In is present in a system. 91 | * 92 | * \param system_indicators to verify. 93 | * 94 | * \return bool true if the StateMachine Add-In is present. 95 | */ 96 | bool verifyStateMachineAddInPresence(const SystemIndicators& system_indicators); 97 | 98 | } 99 | } 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/README.md: -------------------------------------------------------------------------------- 1 | # abb_rws_state_publisher 2 | 3 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 4 | **The package is provided "as-is", and as such no more than limited support can be expected.** 5 | 6 | ## Overview 7 | 8 | The `abb_rws_state_publisher` package provides a ROS node that: 9 | 10 | 1. Attempts to connect to an ABB robot controller via the *Robot Web Services* (`RWS`) interface. 11 | 2. Collects information from the controller about the current system, for example: 12 | - `RobotWare` version and present options. 13 | - Configured mechanical unit groups (*e.g. robots and external axes*). 14 | - Configured `RAPID` tasks. 15 | 3. Starts to periodically poll the controller for runtime data, parse the collected data into ROS messages and publish them to the ROS system. 16 | 17 | Some of the data published to the ROS system include: 18 | 19 | - General system states: 20 | - If motors are on/off. 21 | - If auto/manual operation mode is active. 22 | - If `RAPID` execution is running/stopped. 23 | - State of each `RAPID` task. 24 | - State of each mechanical unit. 25 | - Joint positions of each mechanical unit. 26 | - Runtime state of each `RAPID` program instance of the `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1): 27 | - *Only collected and published if the `StateMachine Add-In` is present in the system*. 28 | 29 | Please see the [rws_state_publisher.launch](launch/rws_state_publisher.launch) file for how to start the node and available node parameters. 30 | 31 | ### Requirements 32 | 33 | - `RobotWare` version `6.07.01` or higher (less than `7.0`). 34 | 35 | Please see the underlying [abb_libegm](https://github.com/ros-industrial/abb_libegm) and [abb_librws](https://github.com/ros-industrial/abb_librws) packages for more details. 36 | 37 | ### Troubleshooting 38 | 39 | *The following table is non-exhaustive, but it should at least give some ideas for things to check.* 40 | 41 | | Issue | Check | 42 | | --- | --- | 43 | | Authentication | The node is currently hardcoded to use the default `RWS` login (`Default User` and `robotics`), but this can be changed in the [code](src/rws_state_publisher.cpp#L122-L123) if needed. | 44 | | Communication | Verify that the correct IP-address has been specified for the robot controller, and that it can be reached on the network:
  1. Using `ping `.
  2. Using a web browser with `http:///rw?debug=1`, which will show a login prompt if connected (*e.g. use the default login above*).
| 45 | | `RobotStudio` | `RobotStudio` simulations blocks remote `RWS` connections by default, which is shown by the `RAPI Unidentified Error` message (*e.g. when using a web browser*).

*Please see this [post](https://forums.robotstudio.com/discussion/12082/using-robotwebservices-to-access-a-remote-virtual-controller) on the official `RobotStudio` forum for how to allow remote `RWS` connections.* | 46 | 47 | ## Acknowledgements 48 | 49 | ### ROSIN Project 50 | 51 |

52 | 53 | rosin_logo 54 | 55 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 56 |

57 | eu_flag 58 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 59 |

60 | 61 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 62 | 63 | ### Special Thanks 64 | 65 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 66 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/include/abb_egm_hardware_interface/egm_state_interface.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_EGM_HARDWARE_INTERFACE_EGM_STATE_INTERFACE_H 38 | #define ABB_EGM_HARDWARE_INTERFACE_EGM_STATE_INTERFACE_H 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | 47 | namespace abb 48 | { 49 | namespace robot 50 | { 51 | 52 | /** 53 | * \brief Resource handle used to read the state of a single EGM channel. 54 | */ 55 | class EGMStateHandle 56 | { 57 | public: 58 | /** 59 | * \brief Creates a default handle. 60 | */ 61 | EGMStateHandle() = default; 62 | 63 | /** 64 | * \brief Creates a handle. 65 | * 66 | * \param name specifying the EGM channel's name. 67 | * \param p_egm_channel_data specifying the EGM channel's data container. 68 | * 69 | * \throw hardware_interface::HardwareInterfaceException if the creation failed. 70 | */ 71 | EGMStateHandle(const std::string& name, const EGMChannelData* p_egm_channel_data) 72 | : 73 | name_{name}, 74 | p_egm_channel_data_{p_egm_channel_data} 75 | { 76 | if (!p_egm_channel_data_) 77 | { 78 | throw hardware_interface::HardwareInterfaceException{"Cannot create handle '" + name_ + "' (null data pointer)"}; 79 | } 80 | } 81 | 82 | /** 83 | * \brief Retrieves the handle's name. 84 | * 85 | * \return std::string& reference to the name. 86 | */ 87 | const std::string& getName() const { return name_; } 88 | 89 | /** 90 | * \brief Retrieves the handle's EGM channel data container. 91 | * 92 | * \return EGMChannelData* pointer to the container. 93 | */ 94 | const EGMChannelData* getEGMChannelDataPtr() const { return p_egm_channel_data_; } 95 | 96 | private: 97 | /** 98 | * \brief The handle's name. 99 | */ 100 | std::string name_; 101 | 102 | /** 103 | * \brief The handle's EGM channel data container. 104 | */ 105 | const EGMChannelData* p_egm_channel_data_{nullptr}; 106 | }; 107 | 108 | /** 109 | * \brief Hardware interface used to read the state of an array of EGM channels. 110 | */ 111 | class EGMStateInterface : public hardware_interface::HardwareResourceManager {}; 112 | 113 | } 114 | } 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/src/verification.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include "abb_robot_cpp_utilities/verification.h" 43 | 44 | namespace 45 | { 46 | /** 47 | * \brief Name for ROS logging in the 'verify' context. 48 | */ 49 | constexpr char ROS_LOG_VERIFY[]{"verify"}; 50 | } 51 | 52 | namespace abb 53 | { 54 | namespace robot 55 | { 56 | namespace utilities 57 | { 58 | 59 | /*********************************************************************************************************************** 60 | * Utility function definitions 61 | */ 62 | 63 | void verifyIPAddress(const std::string& ip_address) 64 | { 65 | Poco::Net::IPAddress poco_ip_address{}; 66 | if(!Poco::Net::IPAddress::tryParse(ip_address, poco_ip_address)) 67 | { 68 | auto error_message{"Invalid IP address '" + ip_address + "' provided"}; 69 | ROS_FATAL_STREAM_NAMED(ROS_LOG_VERIFY, error_message); 70 | throw std::runtime_error{error_message}; 71 | } 72 | } 73 | 74 | void verifyPortNumber(const int port_number) 75 | { 76 | if(port_number < 0 || port_number > std::numeric_limits::max()) 77 | { 78 | auto error_message{"Invalid port number '" + std::to_string(port_number) + "' provided"}; 79 | ROS_FATAL_STREAM_NAMED(ROS_LOG_VERIFY, error_message); 80 | throw std::runtime_error{error_message}; 81 | } 82 | } 83 | 84 | void verifyRate(const double rate) 85 | { 86 | if(rate <= 0.0) 87 | { 88 | auto error_message{"Invalid rate [Hz] '" + std::to_string(rate) + "' provided"}; 89 | ROS_FATAL_STREAM_NAMED(ROS_LOG_VERIFY, error_message); 90 | throw std::runtime_error{error_message}; 91 | } 92 | } 93 | 94 | void verifyRobotWareVersion(const RobotWareVersion& rw_version) 95 | { 96 | if(rw_version.major_number() == 6 && 97 | rw_version.minor_number() < 7 && 98 | rw_version.patch_number() < 1) 99 | { 100 | auto error_message{"Unsupported RobotWare version (" + rw_version.name() + ", need at least 6.07.01)"}; 101 | ROS_FATAL_STREAM_NAMED(ROS_LOG_VERIFY, error_message); 102 | throw std::runtime_error{error_message}; 103 | } 104 | } 105 | 106 | bool verifyStateMachineAddInPresence(const SystemIndicators& system_indicators) 107 | { 108 | return system_indicators.addins().state_machine_1_0() || 109 | system_indicators.addins().state_machine_1_1(); 110 | } 111 | 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /abb_egm_state_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version} LANGUAGES CXX) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # Catkin packages 33 | #----------------------------- 34 | find_package(catkin REQUIRED 35 | COMPONENTS 36 | abb_egm_hardware_interface 37 | abb_egm_msgs 38 | abb_robot_cpp_utilities 39 | controller_interface 40 | pluginlib 41 | realtime_tools 42 | roscpp 43 | ) 44 | 45 | #=========================================================== 46 | # Catkin package specific configurations 47 | #=========================================================== 48 | catkin_package( 49 | INCLUDE_DIRS 50 | include 51 | LIBRARIES 52 | ${PROJECT_NAME} 53 | CATKIN_DEPENDS 54 | abb_egm_hardware_interface 55 | abb_egm_msgs 56 | abb_robot_cpp_utilities 57 | controller_interface 58 | pluginlib 59 | realtime_tools 60 | roscpp 61 | ) 62 | 63 | #=========================================================== 64 | # Settings 65 | #=========================================================== 66 | if(NOT DEFINED BUILD_SHARED_LIBS) 67 | set(BUILD_SHARED_LIBS ON) 68 | endif() 69 | 70 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 71 | message(STATUS "${PROJECT_NAME}: Defaulting build type to RelWithDebInfo") 72 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 73 | endif() 74 | 75 | #=========================================================== 76 | # Build targets 77 | #=========================================================== 78 | set(target_name ${PROJECT_NAME}) 79 | 80 | #----------------------------- 81 | # Library target 82 | #----------------------------- 83 | set( 84 | src_files 85 | src/egm_state_controller.cpp 86 | ) 87 | 88 | add_library(${target_name} ${src_files}) 89 | 90 | target_include_directories(${target_name} PUBLIC 91 | "$" 92 | "$/include>" 93 | "${catkin_INCLUDE_DIRS}" 94 | ) 95 | 96 | target_link_libraries(${target_name} PUBLIC 97 | ${catkin_LIBRARIES} 98 | ) 99 | 100 | target_compile_features(${target_name} PRIVATE cxx_std_14) 101 | 102 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 103 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 104 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 105 | target_compile_options(${target_name} PRIVATE /W4) 106 | endif() 107 | 108 | #=========================================================== 109 | # Install 110 | #=========================================================== 111 | install( 112 | TARGETS 113 | ${PROJECT_NAME} 114 | ARCHIVE DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 115 | LIBRARY DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 116 | RUNTIME DESTINATION "${CATKIN_PACKAGE_BIN_DESTINATION}" 117 | ) 118 | 119 | install( 120 | DIRECTORY include/${PROJECT_NAME}/ 121 | DESTINATION "${CATKIN_PACKAGE_INCLUDE_DESTINATION}" 122 | ) 123 | 124 | install( 125 | FILES 126 | egm_state_controller_plugin.xml 127 | DESTINATION "${CATKIN_PACKAGE_SHARE_DESTINATION}" 128 | ) 129 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/include/abb_robot_cpp_utilities/parameters.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_ROBOT_CPP_UTILITIES_PARAMETERS_H 38 | #define ABB_ROBOT_CPP_UTILITIES_PARAMETERS_H 39 | 40 | #include 41 | 42 | #include 43 | 44 | namespace abb 45 | { 46 | namespace robot 47 | { 48 | namespace utilities 49 | { 50 | 51 | /** 52 | * \brief Gets an optional parameter from the ROS parameter server. 53 | * 54 | * \param nh ROS node handle in the namespace where the parameter should be retrieved from. 55 | * \param key of the parameter. 56 | * \param value for storing the retrieved parameter. 57 | * \param default_value to use if the parameter is not found in the parameter server. 58 | */ 59 | template 60 | void getParameter(ros::NodeHandle& nh, const std::string& key, type& value, const type& default_value); 61 | 62 | /** 63 | * \brief Gets a mandatory parameter from the ROS parameter server. 64 | * 65 | * \param nh ROS node handle in the namespace where the parameter should be retrieved from. 66 | * \param key of the parameter. 67 | * \param value for storing the retrieved parameter. 68 | * 69 | * \throw std::runtime_error if the parameter is not found in the parameter server. 70 | */ 71 | template 72 | void getParameter(ros::NodeHandle& nh, const std::string& key, type& value); 73 | 74 | /** 75 | * \brief Gets an optional list parameter from the ROS parameter server. 76 | * 77 | * \param nh ROS node handle in the namespace where the parameter should be retrieved from. 78 | * \param key of the parameter. 79 | * \param value for storing the retrieved parameter. 80 | * \param default_value to use if the parameter is not found in the parameter server. 81 | */ 82 | template 83 | void getParameter(ros::NodeHandle& nh, 84 | const std::string& key, 85 | std::vector& value, 86 | const std::vector& default_value); 87 | 88 | /** 89 | * \brief Gets a mandatory list parameter from the ROS parameter server. 90 | * 91 | * \param nh ROS node handle in the namespace where the parameter should be retrieved from. 92 | * \param key of the parameter. 93 | * \param value for storing the retrieved parameter. 94 | * 95 | * \throw std::runtime_error if the parameter is not found in the parameter server. 96 | */ 97 | template 98 | void getParameter(ros::NodeHandle& nh, const std::string& key, std::vector& value); 99 | 100 | } 101 | } 102 | } 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/src/initialization.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | 39 | #include 40 | 41 | #include "abb_robot_cpp_utilities/initialization.h" 42 | 43 | namespace 44 | { 45 | /** 46 | * \brief Name for ROS logging in the 'init' context. 47 | */ 48 | constexpr char ROS_LOG_INIT[]{"init"}; 49 | 50 | /** 51 | * \brief Max number of attempts when trying to connect to a robot controller via RWS. 52 | */ 53 | constexpr unsigned int RWS_MAX_CONNECTION_ATTEMPTS{5}; 54 | 55 | /** 56 | * \brief Error message for failed connection attempts when trying to connect to a robot controller via RWS. 57 | */ 58 | constexpr char RWS_CONNECTION_ERROR_MESSAGE[]{"Failed to establish RWS connection to the robot controller"}; 59 | 60 | /** 61 | * \brief Time [s] to wait before trying to reconnect to a robot controller via RWS. 62 | */ 63 | constexpr double RWS_RECONNECTION_WAIT_TIME{1.0}; 64 | } 65 | 66 | namespace abb 67 | { 68 | namespace robot 69 | { 70 | namespace utilities 71 | { 72 | 73 | /*********************************************************************************************************************** 74 | * Utility function definitions 75 | */ 76 | 77 | RobotControllerDescription establishRWSConnection(RWSManager& rws_manager, 78 | const std::string& robot_controller_id, 79 | const bool no_connection_timeout) 80 | { 81 | ros::Duration reconnection_wait_time{RWS_RECONNECTION_WAIT_TIME}; 82 | 83 | unsigned int attempt{0}; 84 | 85 | while(ros::ok() && (no_connection_timeout || attempt++ < RWS_MAX_CONNECTION_ATTEMPTS)) 86 | { 87 | try 88 | { 89 | return rws_manager.collectAndParseSystemData(robot_controller_id); 90 | } 91 | catch(const std::runtime_error& exception) 92 | { 93 | if(!no_connection_timeout) 94 | { 95 | ROS_WARN_STREAM_NAMED(ROS_LOG_INIT, RWS_CONNECTION_ERROR_MESSAGE << " (attempt " << attempt << "/" << 96 | RWS_MAX_CONNECTION_ATTEMPTS << "), reason: '" << exception.what() << "'"); 97 | } 98 | else 99 | { 100 | ROS_WARN_STREAM_NAMED(ROS_LOG_INIT, RWS_CONNECTION_ERROR_MESSAGE << " (waiting indefinitely), reason: '" << 101 | exception.what() << "'"); 102 | } 103 | reconnection_wait_time.sleep(); 104 | } 105 | } 106 | 107 | throw std::runtime_error{RWS_CONNECTION_ERROR_MESSAGE}; 108 | } 109 | 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /abb_egm_state_controller/include/abb_egm_state_controller/egm_state_controller.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_EGM_STATE_CONTROLLER_EGM_STATE_CONTROLLER_H 38 | #define ABB_EGM_STATE_CONTROLLER_EGM_STATE_CONTROLLER_H 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | #include 47 | 48 | #include 49 | 50 | #include 51 | 52 | namespace abb 53 | { 54 | namespace robot 55 | { 56 | 57 | /** 58 | * \brief Controller for publishing the state of Externally Guided Motion (EGM) communication channels. 59 | */ 60 | class EGMStateController : public controller_interface::Controller 61 | { 62 | public: 63 | /** 64 | * \brief Creates a controller. 65 | */ 66 | EGMStateController() = default; 67 | 68 | /** 69 | * \brief Initializes the controller. 70 | * 71 | * \param p_hw specifying the controller's hardware interface. 72 | * \param root_nh for a ROS node handle in the root namespace. 73 | * \param controller_nh for a ROS node handle in the controller's namespace. 74 | * 75 | * \return bool true if the initialization succeeded. 76 | */ 77 | bool init(EGMStateInterface* p_hw, ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh); 78 | 79 | /** 80 | * \brief Starts the controller. 81 | * 82 | * \param time specifying the start time. 83 | */ 84 | void starting(const ros::Time& time); 85 | 86 | /** 87 | * \brief Updates the controller. 88 | * 89 | * \param time specifying the current time. 90 | * \param period specifying the time period since the last update. 91 | */ 92 | void update(const ros::Time& time, const ros::Duration& period); 93 | 94 | /** 95 | * \brief Stops the controller. 96 | * 97 | * \param time specifying the stop time. 98 | */ 99 | void stopping(const ros::Time& time); 100 | 101 | private: 102 | using EGMStatePublisher = realtime_tools::RealtimePublisher; 103 | 104 | /** 105 | * \brief Default publish rate [Hz]. 106 | */ 107 | const double DEFAULT_PUBLISH_RATE{250.0}; 108 | 109 | /** 110 | * \brief The resource handles used by the controller. 111 | */ 112 | std::vector egm_state_handles_; 113 | 114 | /** 115 | * \brief The period that messages should be published at. 116 | */ 117 | ros::Duration publish_period_; 118 | 119 | /** 120 | * \brief The last time messages were published. 121 | */ 122 | ros::Time last_publish_time_; 123 | 124 | /** 125 | * \brief EGM state publisher. 126 | */ 127 | std::shared_ptr p_egm_state_publisher_; 128 | }; 129 | 130 | } 131 | } 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version} LANGUAGES CXX) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # ABB robot controller 33 | # communication package 34 | #----------------------------- 35 | find_package(abb_egm_rws_managers REQUIRED) 36 | 37 | # Extract include directories, because some subsequent 38 | # catkin packages can't seem to build without this. 39 | get_target_property(abb_libegm_INCLUDE_DIRS ${abb_libegm_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 40 | get_target_property(abb_librws_INCLUDE_DIRS ${abb_librws_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 41 | get_target_property(abb_egm_rws_managers_INCLUDE_DIRS ${abb_egm_rws_managers_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 42 | 43 | #----------------------------- 44 | # Catkin packages 45 | #----------------------------- 46 | find_package(catkin REQUIRED 47 | COMPONENTS 48 | abb_egm_msgs 49 | abb_rapid_msgs 50 | abb_rapid_sm_addin_msgs 51 | abb_robot_msgs 52 | roscpp 53 | ) 54 | 55 | #=========================================================== 56 | # Catkin package specific configurations 57 | #=========================================================== 58 | catkin_package( 59 | INCLUDE_DIRS 60 | include 61 | LIBRARIES 62 | ${PROJECT_NAME} 63 | CATKIN_DEPENDS 64 | abb_egm_msgs 65 | abb_rapid_msgs 66 | abb_rapid_sm_addin_msgs 67 | abb_robot_msgs 68 | roscpp 69 | DEPENDS 70 | abb_egm_rws_managers 71 | abb_libegm 72 | abb_librws 73 | Boost 74 | Poco 75 | Protobuf 76 | ) 77 | 78 | #=========================================================== 79 | # Settings 80 | #=========================================================== 81 | if(NOT DEFINED BUILD_SHARED_LIBS) 82 | set(BUILD_SHARED_LIBS ON) 83 | endif() 84 | 85 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 86 | message(STATUS "${PROJECT_NAME}: Defaulting build type to RelWithDebInfo") 87 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 88 | endif() 89 | 90 | #=========================================================== 91 | # Build targets 92 | #=========================================================== 93 | set(target_name ${PROJECT_NAME}) 94 | 95 | #----------------------------- 96 | # Library target 97 | #----------------------------- 98 | set( 99 | src_files 100 | src/initialization.cpp 101 | src/mapping.cpp 102 | src/parameters.cpp 103 | src/verification.cpp 104 | ) 105 | 106 | add_library(${target_name} ${src_files}) 107 | 108 | target_include_directories(${target_name} PUBLIC 109 | "$" 110 | "$/include>" 111 | "${catkin_INCLUDE_DIRS}" 112 | ) 113 | 114 | target_link_libraries(${target_name} PUBLIC 115 | abb_egm_rws_managers::abb_egm_rws_managers 116 | ${catkin_LIBRARIES} 117 | ) 118 | 119 | target_compile_features(${target_name} PRIVATE cxx_std_14) 120 | 121 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 122 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 123 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 124 | target_compile_options(${target_name} PRIVATE /W4) 125 | endif() 126 | 127 | #=========================================================== 128 | # Install 129 | #=========================================================== 130 | install( 131 | TARGETS 132 | ${PROJECT_NAME} 133 | ARCHIVE DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 134 | LIBRARY DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 135 | RUNTIME DESTINATION "${CATKIN_PACKAGE_BIN_DESTINATION}" 136 | ) 137 | 138 | install( 139 | DIRECTORY include/${PROJECT_NAME}/ 140 | DESTINATION "${CATKIN_PACKAGE_INCLUDE_DESTINATION}" 141 | ) 142 | -------------------------------------------------------------------------------- /abb_rws_service_provider/README.md: -------------------------------------------------------------------------------- 1 | # abb_rws_service_provider 2 | 3 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 4 | **The package is provided "as-is", and as such no more than limited support can be expected.** 5 | 6 | ## Overview 7 | 8 | The `abb_rws_service_provider` package provides a ROS node that: 9 | 10 | 1. Attempts to connect to an ABB robot controller via the *Robot Web Services* (`RWS`) interface. 11 | 2. Collects information from the controller about the current system, for example: 12 | - `RobotWare` version and present options. 13 | - Configured mechanical unit groups (*e.g. robots and external axes*). 14 | - Configured `RAPID` tasks. 15 | 3. Exposes a set of ROS services for interacting with the controller from the ROS system. 16 | 17 | Some of the exposed ROS services include: 18 | 19 | - Basic interaction: 20 | - Setting motors on/off. 21 | - Starting/stopping `RAPID` execution. 22 | - Getting/setting of `RAPID` symbols (*e.g. constants and variables*): 23 | - Atomic `RAPID` data types: `bool`, `dnum`, `num` and `string`. 24 | - Complex `RAPID` data structures (*i.e. `RECORD`s, and these are currently only get/set via raw `RAPID` text format*). 25 | - Getting/setting of file contents (*of files in the robot controller's home directory*). 26 | - Getting/setting speed ratio for `RAPID` motions. 27 | - Getting/setting of IO-signals. 28 | - `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1) interaction (*only exposed if the `StateMachine Add-In` is present in the system*): 29 | - `RAPID` interaction: 30 | - Setting custom `RAPID` routines to run (*the routines needs to be predefined in the `RAPID` code*). 31 | - Signaling that the custom `RAPID` routines should be run. 32 | - *Externally Guided Motion* (`EGM`) interaction (*only exposed if the `EGM` option is present*): 33 | - Getting/setting `EGM` `RAPID` settings. 34 | - Starting/stopping `EGM` joint or pose motions. 35 | - Starting/stopping `EGM` position streaming (*i.e. without controlling motions*). 36 | - `SmartGripper` interaction (*only exposed if the `SmartGripper` option is present*): 37 | - Setting commands to run (*e.g. grip in/out or turn on/off vacuum*). 38 | - Signaling that the commands should be run. 39 | 40 | Please see the [rws_service_provider.launch](launch/rws_service_provider.launch) file for how to start the node and available node parameters. Additionally, the ROS node, provided by the `abb_rws_state_publisher` package, is required for most of the service calls. 41 | 42 | ### Requirements 43 | 44 | - `RobotWare` version `6.07.01` or higher (less than `7.0`). 45 | 46 | Please see the underlying [abb_libegm](https://github.com/ros-industrial/abb_libegm) and [abb_librws](https://github.com/ros-industrial/abb_librws) packages for more details. 47 | 48 | ### Troubleshooting 49 | 50 | *The following table is non-exhaustive, but it should at least give some ideas for things to check.* 51 | 52 | | Issue | Check | 53 | | --- | --- | 54 | | Authentication | The node is currently hardcoded to use the default `RWS` login (`Default User` and `robotics`), but this can be changed in the [code](src/rws_service_provider.cpp#L106-L107) if needed. | 55 | | Communication | Verify that the correct IP-address has been specified for the robot controller, and that it can be reached on the network:
  1. Using `ping `.
  2. Using a web browser with `http:///rw?debug=1`, which will show a login prompt if connected (*e.g. use the default login above*).
| 56 | | `RobotStudio` | `RobotStudio` simulations blocks remote `RWS` connections by default, which is shown by the `RAPI Unidentified Error` message (*e.g. when using a web browser*).

*Please see this [post](https://forums.robotstudio.com/discussion/12082/using-robotwebservices-to-access-a-remote-virtual-controller) on the official `RobotStudio` forum for how to allow remote `RWS` connections.* | 57 | | ROS Services | Verify that resource names are correctly spelled, for example:
  • IO-signal name.
  • `RAPID` task, module and symbol names.
  • File name.
  • Etc.
*Please note that most of the exposed services, that sets resources, requires auto mode to be active.* | 58 | 59 | ## Acknowledgements 60 | 61 | ### ROSIN Project 62 | 63 |

64 | 65 | rosin_logo 66 | 67 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 68 |

69 | eu_flag 70 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 71 |

72 | 73 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 74 | 75 | ### Special Thanks 76 | 77 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 78 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version} LANGUAGES CXX) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # ABB robot controller 33 | # communication package 34 | #----------------------------- 35 | find_package(abb_egm_rws_managers REQUIRED) 36 | 37 | #----------------------------- 38 | # Catkin packages 39 | #----------------------------- 40 | find_package(catkin REQUIRED 41 | COMPONENTS 42 | abb_rapid_sm_addin_msgs 43 | abb_robot_cpp_utilities 44 | abb_robot_msgs 45 | roscpp 46 | sensor_msgs 47 | ) 48 | 49 | #=========================================================== 50 | # Catkin package specific configurations 51 | #=========================================================== 52 | catkin_package( 53 | INCLUDE_DIRS 54 | include 55 | LIBRARIES 56 | ${PROJECT_NAME} 57 | CATKIN_DEPENDS 58 | abb_rapid_sm_addin_msgs 59 | abb_robot_cpp_utilities 60 | abb_robot_msgs 61 | roscpp 62 | sensor_msgs 63 | DEPENDS 64 | abb_egm_rws_managers 65 | ) 66 | 67 | #=========================================================== 68 | # Settings 69 | #=========================================================== 70 | if(NOT DEFINED BUILD_SHARED_LIBS) 71 | set(BUILD_SHARED_LIBS ON) 72 | endif() 73 | 74 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 75 | message(STATUS "${PROJECT_NAME}: Defaulting build type to RelWithDebInfo") 76 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 77 | endif() 78 | 79 | #=========================================================== 80 | # Build targets 81 | #=========================================================== 82 | set(target_name ${PROJECT_NAME}) 83 | 84 | #----------------------------- 85 | # Library target 86 | #----------------------------- 87 | set( 88 | src_files 89 | src/rws_state_publisher.cpp 90 | ) 91 | 92 | add_library(${target_name} ${src_files}) 93 | 94 | target_include_directories(${target_name} PUBLIC 95 | "$" 96 | "$/include>" 97 | "${catkin_INCLUDE_DIRS}" 98 | ) 99 | 100 | target_link_libraries(${target_name} PUBLIC 101 | abb_egm_rws_managers::abb_egm_rws_managers 102 | ${catkin_LIBRARIES} 103 | ) 104 | 105 | target_compile_features(${target_name} PRIVATE cxx_std_14) 106 | 107 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 108 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 109 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 110 | target_compile_options(${target_name} PRIVATE /W4) 111 | endif() 112 | 113 | #----------------------------- 114 | # Executable target 115 | #----------------------------- 116 | set( 117 | src_files 118 | src/main.cpp 119 | ) 120 | 121 | add_executable(${target_name}_exe ${src_files}) 122 | 123 | target_link_libraries(${target_name}_exe PRIVATE 124 | ${target_name} 125 | ) 126 | 127 | target_compile_features(${target_name}_exe PRIVATE cxx_std_14) 128 | 129 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 130 | target_compile_options(${target_name}_exe PRIVATE -Wall -Wextra -Wpedantic) 131 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 132 | target_compile_options(${target_name}_exe PRIVATE /W4) 133 | endif() 134 | 135 | set_target_properties(${target_name}_exe 136 | PROPERTIES 137 | OUTPUT_NAME "rws_state_publisher" 138 | ) 139 | 140 | #=========================================================== 141 | # Install 142 | #=========================================================== 143 | install( 144 | TARGETS 145 | ${PROJECT_NAME} 146 | ${PROJECT_NAME}_exe 147 | ARCHIVE DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 148 | LIBRARY DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 149 | RUNTIME DESTINATION "${CATKIN_PACKAGE_BIN_DESTINATION}" 150 | ) 151 | 152 | install( 153 | DIRECTORY include/${PROJECT_NAME}/ 154 | DESTINATION "${CATKIN_PACKAGE_INCLUDE_DESTINATION}" 155 | ) 156 | 157 | install( 158 | DIRECTORY launch 159 | DESTINATION "${CATKIN_PACKAGE_SHARE_DESTINATION}" 160 | ) 161 | -------------------------------------------------------------------------------- /abb_rws_service_provider/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version} LANGUAGES CXX) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # ABB robot controller 33 | # communication package 34 | #----------------------------- 35 | find_package(abb_egm_rws_managers REQUIRED) 36 | 37 | #----------------------------- 38 | # Catkin packages 39 | #----------------------------- 40 | find_package(catkin REQUIRED 41 | COMPONENTS 42 | abb_rapid_sm_addin_msgs 43 | abb_robot_cpp_utilities 44 | abb_robot_msgs 45 | roscpp 46 | ) 47 | 48 | #=========================================================== 49 | # Catkin package specific configurations 50 | #=========================================================== 51 | catkin_package( 52 | INCLUDE_DIRS 53 | include 54 | LIBRARIES 55 | ${PROJECT_NAME} 56 | CATKIN_DEPENDS 57 | abb_rapid_sm_addin_msgs 58 | abb_robot_cpp_utilities 59 | abb_robot_msgs 60 | roscpp 61 | DEPENDS 62 | abb_egm_rws_managers 63 | ) 64 | 65 | #=========================================================== 66 | # Settings 67 | #=========================================================== 68 | if(NOT DEFINED BUILD_SHARED_LIBS) 69 | set(BUILD_SHARED_LIBS ON) 70 | endif() 71 | 72 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 73 | message(STATUS "${PROJECT_NAME}: Defaulting build type to RelWithDebInfo") 74 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 75 | endif() 76 | 77 | #=========================================================== 78 | # Build targets 79 | #=========================================================== 80 | set(target_name ${PROJECT_NAME}) 81 | 82 | #----------------------------- 83 | # Library target 84 | #----------------------------- 85 | set( 86 | src_files 87 | src/rws_service_provider.cpp 88 | src/rws_service_provider_core_srvs.cpp 89 | src/rws_service_provider_sm_srvs.cpp 90 | ) 91 | 92 | add_library(${target_name} ${src_files}) 93 | 94 | target_include_directories(${target_name} PUBLIC 95 | "$" 96 | "$/include>" 97 | "${catkin_INCLUDE_DIRS}" 98 | ) 99 | 100 | target_link_libraries(${target_name} PUBLIC 101 | abb_egm_rws_managers::abb_egm_rws_managers 102 | ${catkin_LIBRARIES} 103 | ) 104 | 105 | target_compile_features(${target_name} PRIVATE cxx_std_14) 106 | 107 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 108 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 109 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 110 | target_compile_options(${target_name} PRIVATE /W4) 111 | endif() 112 | 113 | #----------------------------- 114 | # Executable target 115 | #----------------------------- 116 | set( 117 | src_files 118 | src/main.cpp 119 | ) 120 | 121 | add_executable(${target_name}_exe ${src_files}) 122 | 123 | target_link_libraries(${target_name}_exe PRIVATE 124 | ${target_name} 125 | ) 126 | 127 | target_compile_features(${target_name}_exe PRIVATE cxx_std_14) 128 | 129 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 130 | target_compile_options(${target_name}_exe PRIVATE -Wall -Wextra -Wpedantic) 131 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 132 | target_compile_options(${target_name}_exe PRIVATE /W4) 133 | endif() 134 | 135 | set_target_properties(${target_name}_exe 136 | PROPERTIES 137 | OUTPUT_NAME "rws_service_provider" 138 | ) 139 | 140 | #=========================================================== 141 | # Install 142 | #=========================================================== 143 | install( 144 | TARGETS 145 | ${PROJECT_NAME} 146 | ${PROJECT_NAME}_exe 147 | ARCHIVE DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 148 | LIBRARY DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 149 | RUNTIME DESTINATION "${CATKIN_PACKAGE_BIN_DESTINATION}" 150 | ) 151 | 152 | install( 153 | DIRECTORY include/${PROJECT_NAME}/ 154 | DESTINATION "${CATKIN_PACKAGE_INCLUDE_DESTINATION}" 155 | ) 156 | 157 | install( 158 | DIRECTORY launch 159 | DESTINATION "${CATKIN_PACKAGE_SHARE_DESTINATION}" 160 | ) 161 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/include/abb_egm_hardware_interface/egm_controller_stopper.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_EGM_HARDWARE_INTERFACE_EGM_CONTROLLER_STOPPER_H 38 | #define ABB_EGM_HARDWARE_INTERFACE_EGM_CONTROLLER_STOPPER_H 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | #include 47 | 48 | #include 49 | 50 | namespace abb 51 | { 52 | namespace robot 53 | { 54 | 55 | /** 56 | * \brief Utility class for observing EGM channel states and, if needed, stopping ros_control controllers. 57 | * 58 | * Note: A user provided list specifies which controllers that are allowed to keep running if EGM becomes inactive. 59 | */ 60 | class EGMControllerStopper 61 | { 62 | public: 63 | /** 64 | * \brief Creates a stopper of ros_control controllers. 65 | * 66 | * \param nh_params node handle (in the namespace where ROS parameters should be gathered from). 67 | * \param nh_msgs node handle (in the namespace where ROS messages should be subscribed to). 68 | * \param nh_srvs node handle (in the namespace where ROS services should be called in). 69 | * 70 | * \throw std::runtime_error if the creation failed (e.g. any initialization step fails). 71 | */ 72 | EGMControllerStopper(ros::NodeHandle& nh_params, ros::NodeHandle& nh_msgs, ros::NodeHandle& nh_srvs); 73 | 74 | private: 75 | /** 76 | * \brief Parameter handler for gathering required ROS parameters. 77 | */ 78 | struct ParameterHandler 79 | { 80 | /** 81 | * \brief Creates a parameter handler. 82 | * 83 | * \param nh node handle in the namespace where ROS parameters should be gathered from. 84 | */ 85 | ParameterHandler(ros::NodeHandle& nh); 86 | 87 | /** 88 | * \brief Indicator for whether the node is allowed to wait indefinitely for ROS services. 89 | * 90 | * Note: This only applies during the node's initialization phase. 91 | */ 92 | bool no_service_timeout; 93 | 94 | /** 95 | * \brief List of user specifed ros_control controllers which are allowed to keep running if EGM becomes inactive. 96 | */ 97 | std::vector controllers_ok_to_keep_running; 98 | }; 99 | 100 | /** 101 | * \brief Callback for processing EGM channel states. 102 | * 103 | * \param message to process. 104 | */ 105 | void egmStatesCallback(const abb_egm_msgs::EGMState::ConstPtr& message); 106 | 107 | /** 108 | * \brief Checks and stops ros_control controllers that are not allowed to keep running. 109 | */ 110 | void checkAndStopControllers(); 111 | 112 | /** 113 | * \brief Handler for gathering required ROS parameters. 114 | */ 115 | ParameterHandler parameters_; 116 | 117 | /** 118 | * \brief Subscriber for EGM channel states. 119 | */ 120 | ros::Subscriber egm_states_subscriber_; 121 | 122 | /** 123 | * \brief Service client for requesting a list of currently loaded ros_control controllers. 124 | */ 125 | ros::ServiceClient list_controllers_client_; 126 | 127 | /** 128 | * \brief Service client for requesting a switch (i.a. stopping) of ros_control controllers. 129 | */ 130 | ros::ServiceClient switch_controllers_client_; 131 | 132 | /** 133 | * \brief The previously received EGM activity state. 134 | */ 135 | bool egm_previously_active_; 136 | 137 | /** 138 | * \brief Service request/response for list of currently loaded ros_control controllers. 139 | */ 140 | controller_manager_msgs::ListControllers list_controllers_; 141 | 142 | /** 143 | * \brief Service request/response for switching (i.a. stopping) ros_control controllers. 144 | */ 145 | controller_manager_msgs::SwitchController switch_controllers_; 146 | }; 147 | 148 | } 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/include/abb_rws_state_publisher/rws_state_publisher.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_RWS_STATE_PUBLISHER_RWS_STATE_PUBLISHER_H 38 | #define ABB_RWS_STATE_PUBLISHER_RWS_STATE_PUBLISHER_H 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | 45 | namespace abb 46 | { 47 | namespace robot 48 | { 49 | 50 | /** 51 | * \brief State publisher that collects the current system states from an ABB robot controller via RWS. 52 | */ 53 | class RWSStatePublisher 54 | { 55 | public: 56 | /** 57 | * \brief Creates a state publisher. 58 | * 59 | * \param nh_params node handle (in the namespace where ROS parameters should be gathered from). 60 | * \param nh_msgs node handle (in the namespace where ROS messages should be published in). 61 | * 62 | * \throw std::runtime_error if the creation failed (e.g. any initialization step fails). 63 | */ 64 | RWSStatePublisher(ros::NodeHandle& nh_params, ros::NodeHandle& nh_msgs); 65 | 66 | private: 67 | /** 68 | * \brief Parameter handler for gathering required ROS parameters. 69 | */ 70 | struct ParameterHandler 71 | { 72 | /** 73 | * \brief Creates a parameter handler. 74 | * 75 | * \param nh node handle in the namespace where ROS parameters should be gathered from. 76 | * 77 | * \throw std::runtime_error if the creation failed (e.g. missing any mandatory ROS parameter). 78 | */ 79 | ParameterHandler(ros::NodeHandle& nh); 80 | 81 | /** 82 | * \brief IP address for the robot controller's RWS server. 83 | */ 84 | std::string robot_ip; 85 | 86 | /** 87 | * \brief Port number for the robot controller's RWS server. 88 | */ 89 | int robot_port; 90 | 91 | /** 92 | * \brief Arbitrary user nickname/identifier for the robot controller. 93 | */ 94 | std::string robot_nickname; 95 | 96 | /** 97 | * \brief Indicator for whether the node is allowed to wait indefinitely for the robot controller. 98 | * 99 | * Note: This only applies during the node's initialization phase. 100 | */ 101 | bool no_connection_timeout; 102 | 103 | /** 104 | * \brief Polling rate [Hz] for collecting system states and publishing of ROS messages. 105 | */ 106 | double polling_rate; 107 | }; 108 | 109 | /** 110 | * \brief Timer callback for polling and publishing of system states. 111 | */ 112 | void pollingTimerCallback(const ros::TimerEvent&); 113 | 114 | /** 115 | * \brief Handler for gathering required ROS parameters. 116 | */ 117 | ParameterHandler parameters_; 118 | 119 | /** 120 | * \brief Manager for handling RWS communication with the robot controller. 121 | */ 122 | RWSManager rws_manager_; 123 | 124 | /** 125 | * \brief Description of the connected robot controller. 126 | */ 127 | RobotControllerDescription robot_controller_description_; 128 | 129 | /** 130 | * \brief Data about the robot controller's system state. 131 | */ 132 | SystemStateData system_state_data_; 133 | 134 | /** 135 | * \brief Motion data for each mechanical unit defined in the robot controller. 136 | */ 137 | MotionData motion_data_; 138 | 139 | /** 140 | * \brief Polling rate for collecting and publishing system states. 141 | */ 142 | ros::Rate polling_rate_; 143 | 144 | /** 145 | * \brief Timer for polling and publishing of system states. 146 | */ 147 | ros::Timer polling_timer_; 148 | 149 | /** 150 | * \brief Publisher for joint states. 151 | */ 152 | ros::Publisher joint_state_publisher_; 153 | 154 | /** 155 | * \brief Publisher for general system states. 156 | */ 157 | ros::Publisher system_state_publisher_; 158 | 159 | /** 160 | * \brief Publisher for RobotWare StateMachine Add-In runtime states. 161 | * 162 | * Note: Only used if the Add-In is present in the system. 163 | */ 164 | ros::Publisher sm_runtime_state_publisher_; 165 | }; 166 | 167 | } 168 | } 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/README.md: -------------------------------------------------------------------------------- 1 | # abb_egm_hardware_interface 2 | 3 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 4 | **The package is provided "as-is", and as such no more than limited support can be expected.** 5 | 6 | ## Overview 7 | 8 | The `abb_egm_hardware_interface` package provides: 9 | 10 | - A `ros_control`-based hardware interface, for communicating with ABB robots via the *Externally Guided Motion* (`EGM`) interface: 11 | - Recommendations: 12 | - Use `RobotStudio` simulations before testing with real robots. 13 | - Use the latest supported `RobotWare` version to get the best `EGM` performance. 14 | - The hardware interface sets up `EGM` servers that the robot can send feedback messages to, and receive motion commands from: 15 | - It is always the robot that initiates `EGM` communication sessions. 16 | - The hardware interface will only allow `ros_control` controllers to be started if there is already an active `EGM` communication session: 17 | - Users can specify a list of controllers that are always ok to start (*e.g. passive state controllers*). 18 | - For `MultiMove` systems it is important to note that: 19 | - The ROS side configurations must specify correct names for the mechanical unit groups that are intended to be used with `EGM`. 20 | - Activation/deactivation of mechanical units, after the hardware interface has been initialized, is not handled by the hardware interface and can lead to unexpected behavior. 21 | - A ROS node that uses the hardware interface, together with a `ros_control` controller manager, to run a control loop. 22 | - A ROS node for stopping `ros_control` controllers when `EGM` sessions ends: 23 | - Users can specify a list of controllers that are ok to keep running (*e.g. passive state controllers*). 24 | 25 | **Please note that this package is only recommended for advanced users.** 26 | 27 | Please see the [egm_hardware_interface.launch](launch/egm_hardware_interface.launch) file for how to start the node and available node parameters. Additionally, the ROS node, provided by the `abb_rws_service_provider` package, is required during initialization of the hardware interface. 28 | 29 | Please see the [config](config) folder for configuration examples for a few different use cases. 30 | 31 | ### Requirements 32 | 33 | - `RobotWare` version `6.07.01` or higher (less than `7.0`). 34 | 35 | Please see the underlying [abb_libegm](https://github.com/ros-industrial/abb_libegm) and [abb_librws](https://github.com/ros-industrial/abb_librws) packages for more details. 36 | 37 | ### Troubleshooting 38 | 39 | *The following table is non-exhaustive, but it should at least give some ideas for things to check.* 40 | 41 | | Issue | Check | 42 | | --- | --- | 43 | | Communication | If the `FlexPendant` shows the `No data from UdpUc device` message it means that the robot sent out `EGM` `UDP` messages, but it did not receive any reply:
  • Verify that the correct remote IP-address, and port number, has been specified in the the robot's system configurations: *`RobotStudio` > Controller tab > Configuration > Communication > Transmission Protocol* (check the `UDPUC` instances).
  • Verify that no firewall is blocking `UDP` communication on the desired ports.
| 44 | | Utilization rate | If the hardware interface prints messages about an `EGM` channel's utilization rate being above `100%`, it means that the desired commands sent by the user are too aggressive and they should be reduced. | 45 | | Motion (*robot side settings*) | System configurations:
  • See *`RobotStudio` > Controller tab > Configuration > Motion > External Motion Interface Data* (the `Filtering`/`Raw` level can for example affect how well references are tracked).
Important `EGM` `RAPID` parameters:
  • The `\MaxSpeedDeviation` parameter can be used to trim acceleration/deceleration, and it also seems to limit the maximum allowed joint speed (*ROS side velocity limits should be less than or equal to this this parameter*).
  • Pure velocity control requires the `\PosCorrGain` parameter to be set to `0`.
  • Make sure that the correct `tooldata` has be specified in the `RAPID` code with either `\Tool` or `\TLoad` (*i.e. if modal payload mode is set to `No` in the system configurations*).
  • If the `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1) is present, and if the ROS node provided by the `abb_rws_service_provider` package is used, then ROS services are exposed to get/set the `EGM` `RAPID` settings directly from the ROS side.
*Please see the *Application manual - Externally Guided Motion* (*document ID: `3HAC073319-001`, revision: `B`*) for a more detailed description of `EGM` settings and capabilities.* | 46 | | Motion (*ROS side settings*) | The hardware interface registers `PositionJointSoftLimitsInterface` and `VelocityJointSoftLimitsInterface` interfaces, which users can, for example, configure with velocity limits for each joint (*conservative limits are set per default*).

*Please see the [joint_limits_interface](https://github.com/ros-controls/ros_control/wiki/joint_limits_interface) package for more details about how joint limit configurations can be specified.* | 47 | 48 | ## Acknowledgements 49 | 50 | ### ROSIN Project 51 | 52 |

53 | 54 | rosin_logo 55 | 56 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 57 |

58 | eu_flag 59 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 60 |

61 | 62 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 63 | 64 | ### Special Thanks 65 | 66 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 67 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/src/parameters.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | 39 | #include "abb_robot_cpp_utilities/mapping.h" 40 | #include "abb_robot_cpp_utilities/parameters.h" 41 | 42 | namespace 43 | { 44 | /** 45 | * \brief Name for ROS logging in the 'param' context. 46 | */ 47 | constexpr char ROS_LOG_PARAM[]{"param"}; 48 | } 49 | 50 | namespace abb 51 | { 52 | namespace robot 53 | { 54 | namespace utilities 55 | { 56 | 57 | /*********************************************************************************************************************** 58 | * Utility template function definitions 59 | */ 60 | 61 | template 62 | void getParameter(ros::NodeHandle& nh, const std::string& key, type& value, const type& default_value) 63 | { 64 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Check for (optional) parameter '" << key << "'"); 65 | 66 | if(nh.param(key, value, default_value)) 67 | { 68 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Found parameter '" << key << "'='" << value << "'"); 69 | } 70 | else 71 | { 72 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Parameter '" << key << "' not found, using default value '" << value << "'"); 73 | } 74 | } 75 | 76 | template 77 | void getParameter(ros::NodeHandle& nh, const std::string& key, type& value) 78 | { 79 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Check for (mandatory) parameter '" << key << "'"); 80 | 81 | if(!nh.getParam(key, value)) 82 | { 83 | auto error_message{"Parameter '" + key + "' not found"}; 84 | ROS_FATAL_STREAM_NAMED(ROS_LOG_PARAM, error_message); 85 | throw std::runtime_error{error_message}; 86 | } 87 | 88 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Found parameter '" << key << "'='" << value << "'"); 89 | } 90 | 91 | template 92 | void getParameter(ros::NodeHandle& nh, 93 | const std::string& key, 94 | std::vector& value, 95 | const std::vector& default_value) 96 | { 97 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Check for (optional) parameter '" << key << "'"); 98 | 99 | if(nh.param>(key, value, default_value)) 100 | { 101 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Found parameter '" << key << "'='" << mapVectorToString(value) << "'"); 102 | } 103 | else 104 | { 105 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Parameter '" << key << "' not found, using default value '" << 106 | mapVectorToString(value) << "'"); 107 | } 108 | } 109 | 110 | template 111 | void getParameter(ros::NodeHandle& nh, const std::string& key, std::vector& value) 112 | { 113 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Check for (mandatory) parameter '" << key << "'"); 114 | 115 | if(!nh.getParam(key, value)) 116 | { 117 | auto error_message{"Parameter '" + key + "' not found"}; 118 | ROS_FATAL_STREAM_NAMED(ROS_LOG_PARAM, error_message); 119 | throw std::runtime_error{error_message}; 120 | } 121 | 122 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_PARAM, "Found parameter '" << key << "'='" << mapVectorToString(value) << "'"); 123 | } 124 | 125 | /*********************************************************************************************************************** 126 | * Utility template function instantiations 127 | */ 128 | 129 | template void getParameter(ros::NodeHandle&, const std::string&, std::string&, const std::string&); 130 | template void getParameter(ros::NodeHandle&, const std::string&, bool&, const bool&); 131 | template void getParameter(ros::NodeHandle&, const std::string&, int&, const int&); 132 | template void getParameter(ros::NodeHandle&, const std::string&, double&, const double&); 133 | 134 | template void getParameter(ros::NodeHandle&, const std::string&, std::string&); 135 | template void getParameter(ros::NodeHandle&, const std::string&, bool&); 136 | template void getParameter(ros::NodeHandle&, const std::string&, int&); 137 | template void getParameter(ros::NodeHandle&, const std::string&, double&); 138 | 139 | template void getParameter(ros::NodeHandle&, 140 | const std::string&, 141 | std::vector&, 142 | const std::vector&); 143 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&, const std::vector&); 144 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&, const std::vector&); 145 | template void getParameter(ros::NodeHandle&, 146 | const std::string&, 147 | std::vector&, 148 | const std::vector&); 149 | 150 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&); 151 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&); 152 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&); 153 | template void getParameter(ros::NodeHandle&, const std::string&, std::vector&); 154 | 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abb_robot_driver 2 | 3 | ![CI - Ubuntu Bionic](https://github.com/ros-industrial/abb_robot_driver/workflows/CI%20-%20Ubuntu%20Bionic/badge.svg) 4 | ![CI - Ubuntu Focal](https://github.com/ros-industrial/abb_robot_driver/workflows/CI%20-%20Ubuntu%20Focal/badge.svg) 5 | [![Github Issues](https://img.shields.io/github/issues/ros-industrial/abb_robot_driver.svg)](http://github.com/ros-industrial/abb_robot_driver/issues) 6 | 7 | [![license - bsd 3 clause](https://img.shields.io/:license-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 8 | 9 | [![support level: community](https://img.shields.io/badge/support%20level-community-lightgray.svg)](http://rosindustrial.org/news/2016/10/7/better-supporting-a-growing-ros-industrial-software-platform) 10 | 11 | **Please note that the included packages have not been productized, and that academia is the intended audience.**\ 12 | **The packages are provided "as-is", and as such no more than limited support can be expected.** 13 | 14 | ## Overview 15 | 16 | ROS packages intended to ease interaction between ABB robot controllers and ROS-based systems, by providing *ready-to-run* ROS nodes. 17 | 18 |

19 | 20 |
21 | Connecting ABB robots, people and ROS systems together. 22 |

23 | 24 | The included (*principal*) packages are briefly described in the following table: 25 | 26 | | Package | Description | 27 | | --- | --- | 28 | | [abb_rws_state_publisher](abb_rws_state_publisher) | Provides a ROS node that continuously polls an ABB robot controller for system states, which then are parsed into ROS messages and published to the ROS system. | 29 | | [abb_rws_service_provider](abb_rws_service_provider) | Provides a ROS node that exposes ROS services, for *discrete interaction* with an ABB robot controller, like starting/stopping the `RAPID` program and reading/writing of IO-signals. | 30 | | [abb_egm_hardware_interface](abb_egm_hardware_interface) | Provides ROS nodes for:
  • Running a [ros_control](http://wiki.ros.org/ros_control)-based hardware interface, for *direct motion control* of ABB robots (via the *Externally Guided Motion* (`EGM`) interface).
  • Automatically stopping `ros_control` controllers when `EGM` communication sessions ends *(a user-provided list can specify controllers that are ok to keep running*).
***This package is only recommended for advanced users.*** | 31 | 32 | Please see each package for more details (*e.g. additional requirements, limitations and troubleshooting*). 33 | 34 | It is recommended to utilize the `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1) to ease the setup of the ABB robot controller system. The `StateMachine Add-In` is optional, however, without it, the driver nodes will only be able to provide basic interaction with ABB robots. 35 | 36 | ## Build Instructions 37 | 38 | It is assumed that [ROS has been installed](http://wiki.ros.org/ROS/Installation) on the system in question. 39 | 40 | *Note that the included packages have mainly been tested with ROS Melodic (on both Ubuntu and Windows).* 41 | 42 | ### catkin_tools 43 | 44 | As some of the dependencies of this driver are plain CMake packages (instead of Catkin packages), they cannot be built using vanilla [catkin](http://wiki.ros.org/catkin), but require the use of either `catkin_make_isolated` or [catkin_tools](https://catkin-tools.readthedocs.io/en/latest). 45 | The instructions in the rest of this section will assume `catkin_tools` will be used. 46 | In case of using `catkin_make_isolated`, be sure to update commands where necessary. 47 | 48 | As workspaces cannot be built with both vanilla `catkin` and `catkin_tools`, if you already have a workspace and would like to *add* the packages of this driver to that workspace, be sure to clean the workspace prior to building it, as you will encounter errors otherwise. 49 | 50 | ### vcstool 51 | 52 | The instructions below assume [vcstool](https://github.com/dirk-thomas/vcstool) is installed. 53 | Refer to [How to install vcstool?](https://github.com/dirk-thomas/vcstool#how-to-install-vcstool) in the `vcstool` readme for more information on how to install it on various OS. 54 | 55 | ### Building the Packages 56 | 57 | The following instructions assume that a [Catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace) has been created at `$HOME/catkin_ws` and that the *source space* is at `$HOME/catkin_ws/src`. Update paths appropriately if they are different on the build machine. 58 | 59 | The following instructions should build the main branches of all required repositories on a ROS Melodic system: 60 | 61 | ```bash 62 | # Change to the root of the Catkin workspace. 63 | cd $HOME/catkin_ws 64 | mkdir -p src 65 | 66 | # Use vcstool to clone all required repositories into the 'src' space. 67 | vcs import src --input https://github.com/ros-industrial/abb_robot_driver/raw/master/pkgs.repos 68 | 69 | # Check build dependencies. 70 | # First update the local rosdep database. 71 | rosdep update 72 | 73 | # And then ask rosdep to install any missing dependencies for us. 74 | # NOTE: This may install additional packages, depending on the software installed 75 | # on the machine. Be sure to check each command rosdep wants to run. 76 | rosdep install --from-paths src --ignore-src --rosdistro melodic 77 | 78 | # Finally build the workspace (using catkin_tools). 79 | catkin build 80 | ``` 81 | 82 | If no errors were reported as part of the `catkin build` command, the build has succeeded and the driver should now be usable. 83 | 84 | ### Activating the Workspace 85 | 86 | Finally, activate the workspace to get access to the packages just built: 87 | 88 | ```bash 89 | $ source $HOME/catkin_ws/devel/setup.bash 90 | ``` 91 | 92 | At this point all packages should be usable (ie: `roslaunch` should be able to auto-complete package names starting with `abb_..`). In case the workspace contains additional packages (i.e.: not from this repository), those should also still be available. 93 | 94 | ## Bringup Examples 95 | 96 | See [abb_robot_bringup_examples](abb_robot_bringup_examples) for some basic examples of how to configure, launch and use the included ROS nodes. 97 | 98 | ## Acknowledgements 99 | 100 | ### ROSIN Project 101 | 102 |

103 | 104 | rosin_logo 105 | 106 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 107 |

108 | eu_flag 109 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 110 |

111 | 112 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 113 | 114 | ### Special Thanks 115 | 116 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 117 | -------------------------------------------------------------------------------- /abb_egm_state_controller/src/egm_state_controller.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | 43 | #include "abb_egm_state_controller/egm_state_controller.h" 44 | 45 | namespace 46 | { 47 | /** 48 | * \brief Name for ROS logging in the 'init' context. 49 | */ 50 | constexpr char ROS_LOG_INIT[]{"init"}; 51 | } 52 | 53 | namespace abb 54 | { 55 | namespace robot 56 | { 57 | 58 | /*********************************************************************************************************************** 59 | * Class definitions: EGMStateController 60 | */ 61 | 62 | /*********************************************************** 63 | * Primary methods 64 | */ 65 | 66 | bool EGMStateController::init(EGMStateInterface* p_hw, ros::NodeHandle& root_nh, ros::NodeHandle& controller_nh) 67 | { 68 | //-------------------------------------------------------- 69 | // Verify the hardware interface 70 | //-------------------------------------------------------- 71 | if(!p_hw) 72 | { 73 | ROS_FATAL_STREAM_NAMED(ROS_LOG_INIT, "Hardware interface has not been not allocated"); 74 | return false; 75 | } 76 | 77 | // Verify that the interface have one or more resources. 78 | if(p_hw->getNames().size() >= 1) 79 | { 80 | try 81 | { 82 | // Get the handles (throws an exception on failure). 83 | for(const auto& name : p_hw->getNames()) 84 | { 85 | egm_state_handles_.push_back(p_hw->getHandle(name)); 86 | } 87 | } 88 | catch(...) 89 | { 90 | ROS_FATAL_STREAM_NAMED(ROS_LOG_INIT, "Failed to get resource handles from hardware interface"); 91 | return false; 92 | } 93 | } 94 | else 95 | { 96 | ROS_FATAL_STREAM_NAMED(ROS_LOG_INIT, "Hardware interface has less than 1 resources"); 97 | return false; 98 | } 99 | 100 | //-------------------------------------------------------- 101 | // Get parameter from the parameter server 102 | //-------------------------------------------------------- 103 | try 104 | { 105 | double publish_rate{DEFAULT_PUBLISH_RATE}; 106 | utilities::getParameter(controller_nh, "publish_rate", publish_rate, DEFAULT_PUBLISH_RATE); 107 | utilities::verifyRate(publish_rate); 108 | publish_period_ = ros::Duration(1.0/publish_rate); 109 | } 110 | catch(...) 111 | { 112 | return false; 113 | } 114 | 115 | //-------------------------------------------------------- 116 | // Setup publisher 117 | //-------------------------------------------------------- 118 | p_egm_state_publisher_.reset(new EGMStatePublisher(root_nh, "egm_states", 1)); 119 | 120 | // Allocate ROS messages. 121 | for(const auto& handle : egm_state_handles_) 122 | { 123 | auto p_data{handle.getEGMChannelDataPtr()}; 124 | 125 | abb_egm_msgs::EGMChannelState channel{}; 126 | 127 | // General information. 128 | channel.name = handle.getName(); 129 | channel.active = p_data->is_active; 130 | 131 | // Status information. 132 | channel.egm_convergence_met = p_data->input.status().egm_convergence_met(); 133 | channel.egm_client_state = utilities::map(p_data->input.status().egm_state()); 134 | channel.motor_state = utilities::map(p_data->input.status().motor_state()); 135 | channel.rapid_execution_state = utilities::map(p_data->input.status().rapid_execution_state()); 136 | channel.utilization_rate = p_data->input.status().utilization_rate(); 137 | 138 | p_egm_state_publisher_->msg_.egm_channels.push_back(channel); 139 | } 140 | 141 | return true; 142 | } 143 | 144 | void EGMStateController::starting(const ros::Time& time) { last_publish_time_ = time; } 145 | 146 | void EGMStateController::update(const ros::Time& time, const ros::Duration& period) 147 | { 148 | (void) period; 149 | 150 | if(last_publish_time_ + publish_period_ < time) 151 | { 152 | last_publish_time_ += publish_period_; 153 | 154 | //------------------------------------------------------ 155 | // Try to publish EGM state 156 | //------------------------------------------------------ 157 | if(p_egm_state_publisher_->trylock()) 158 | { 159 | p_egm_state_publisher_->msg_.header.stamp = time; 160 | 161 | for(size_t i = 0; i < egm_state_handles_.size() && i < p_egm_state_publisher_->msg_.egm_channels.size(); ++i) 162 | { 163 | auto p_data{egm_state_handles_[i].getEGMChannelDataPtr()}; 164 | 165 | // Status information. 166 | auto& channel{p_egm_state_publisher_->msg_.egm_channels[i]}; 167 | channel.active = p_data->is_active; 168 | 169 | // Status information. 170 | channel.egm_convergence_met = p_data->input.status().egm_convergence_met(); 171 | channel.egm_client_state = utilities::map(p_data->input.status().egm_state()); 172 | channel.motor_state = utilities::map(p_data->input.status().motor_state()); 173 | channel.rapid_execution_state = utilities::map(p_data->input.status().rapid_execution_state()); 174 | channel.utilization_rate = p_data->input.status().utilization_rate(); 175 | } 176 | 177 | p_egm_state_publisher_->unlockAndPublish(); 178 | } 179 | } 180 | } 181 | 182 | void EGMStateController::stopping(const ros::Time& time) { (void) time; } 183 | 184 | } 185 | } 186 | 187 | PLUGINLIB_EXPORT_CLASS(abb::robot::EGMStateController, controller_interface::ControllerBase) 188 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/src/egm_hardware_interface_main.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | #include 45 | 46 | #include 47 | 48 | #include 49 | 50 | namespace 51 | { 52 | /** 53 | * \brief Name for ROS logging in the 'main' context. 54 | */ 55 | constexpr char ROS_LOG_MAIN[]{"main"}; 56 | 57 | /** 58 | * \brief Timeout [s] for waiting on ROS services. 59 | */ 60 | constexpr double ROS_SERVICE_TIMEOUT{30.0}; 61 | } 62 | 63 | /** 64 | * \brief Gets a ABB robot controller description via a ROS service call. 65 | * 66 | * Note: This function is a workaround for the fact that the description is collected 67 | * during runtime (in another node), and is not know at launch time. 68 | * 69 | * \param nh specifying a node handle to use for reading and setting ROS parameters. 70 | * 71 | * \throw std::runtime_error if the description could not be gotten. 72 | */ 73 | void getRobotControllerDescription(ros::NodeHandle& nh); 74 | 75 | int main(int argc, char** argv) 76 | { 77 | //-------------------------------------------------------- 78 | // Preparations 79 | //-------------------------------------------------------- 80 | ros::init(argc, argv, "egm_hardware_interface"); 81 | 82 | // Create a node handle, in the namespace where the 83 | // hardware interface's ROS interfaces should operate in. 84 | // 85 | // Note: Using "egm" to indicate that the ROS interfaces 86 | // are related to Externally Guided Motion (EGM) 87 | // communication. 88 | ros::NodeHandle nh{"egm"}; 89 | 90 | // Create a node handle, in the namespace where the 91 | // hardware interface should read parameters from. 92 | ros::NodeHandle nh_hw{"~"}; 93 | 94 | //-------------------------------------------------------- 95 | // Start node execution 96 | //-------------------------------------------------------- 97 | try 98 | { 99 | // Process ROS interfaces in the background. 100 | ros::AsyncSpinner spinner{4}; 101 | spinner.start(); 102 | 103 | // Get a description of the targeted ABB robot controller. 104 | getRobotControllerDescription(nh_hw); 105 | 106 | // Create and initialize the hardware interface. 107 | abb::robot::EGMHardwareInterface hw{}; 108 | hw.init(nh, nh_hw); 109 | 110 | // Create a controller manager, to manage the 111 | // hardware interface and active controllers. 112 | controller_manager::ControllerManager cm{&hw, nh}; 113 | 114 | // Run the control loop. 115 | ros::Time time_now{}; 116 | ros::Duration period{1.0/250.0}; 117 | while(ros::ok()) 118 | { 119 | period = hw.waitForMessage(); 120 | 121 | time_now = ros::Time::now(); 122 | hw.read(time_now, period); 123 | cm.update(time_now, period, hw.resetNeeded()); 124 | hw.write(time_now, period); 125 | } 126 | } 127 | catch(const std::runtime_error& exception) 128 | { 129 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Runtime error: '" << exception.what() << "'"); 130 | return EXIT_FAILURE; 131 | } 132 | catch(const std::invalid_argument& exception) 133 | { 134 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Invalid argument: '" << exception.what() << "'"); 135 | return EXIT_FAILURE; 136 | } 137 | catch(const std::out_of_range& exception) 138 | { 139 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Out of range: '" << exception.what() << "'"); 140 | return EXIT_FAILURE; 141 | } 142 | catch(const std::exception& exception) 143 | { 144 | ROS_FATAL_STREAM_NAMED(ROS_LOG_MAIN, "Exception '" << exception.what() << "'"); 145 | return EXIT_FAILURE; 146 | } 147 | catch(...) 148 | { 149 | ROS_FATAL_NAMED(ROS_LOG_MAIN, "Unknown exception"); 150 | return EXIT_FAILURE; 151 | } 152 | 153 | return EXIT_SUCCESS; 154 | } 155 | 156 | void getRobotControllerDescription(ros::NodeHandle& nh) 157 | { 158 | // Get indicator for allowing no ROS service timeout during initialization. 159 | bool no_service_timeout{false}; 160 | abb::robot::utilities::getParameter(nh, "no_service_timeout", no_service_timeout, false); 161 | 162 | // Components for a ROS service to get a description 163 | // of the targeted robot controller. 164 | // 165 | // Note: The description is assumed to have been 166 | // collected via RWS, and parsed, in another ROS 167 | // node, which provides a ROS service to share 168 | // the description. 169 | std::string service_name{"rws/get_robot_controller_description"}; 170 | abb_robot_msgs::GetRobotControllerDescription service_result{}; 171 | 172 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_MAIN, "Wait for ROS service '" << service_name << "'"); 173 | 174 | // Wait for the ROS service. 175 | if(no_service_timeout) 176 | { 177 | ros::service::waitForService(service_name); 178 | } 179 | else 180 | { 181 | if(!ros::service::waitForService(service_name, ros::Duration(ROS_SERVICE_TIMEOUT))) 182 | { 183 | throw std::runtime_error{"Timed out while waiting for ROS service '" + service_name + "'"}; 184 | } 185 | } 186 | 187 | // Call the ROS service. 188 | if(!ros::service::call(service_name, service_result)) 189 | { 190 | throw std::runtime_error{"Failed to call ROS service '" + service_name + "'"}; 191 | } 192 | 193 | // Set the robot controller description parameter for 194 | // the hardware interface's initialization. 195 | // 196 | // Note: This deviates from best practices and 197 | // is only used as a workaround because 198 | // the robot controller description is 199 | // not know at launch time. 200 | nh.setParam("robot_controller_description", service_result.response.description); 201 | } 202 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/src/egm_controller_stopper.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include "abb_egm_hardware_interface/egm_controller_stopper.h" 43 | 44 | namespace 45 | { 46 | /** 47 | * \brief Name for ROS logging in the 'init' context. 48 | */ 49 | constexpr char ROS_LOG_INIT[]{"init"}; 50 | 51 | /** 52 | * \brief Name for ROS logging in the 'runtime' context. 53 | */ 54 | constexpr char ROS_LOG_RUNTIME[]{"runtime"}; 55 | 56 | /** 57 | * \brief Timeout [s] for waiting on ROS services. 58 | */ 59 | constexpr double ROS_SERVICE_TIMEOUT{30.0}; 60 | } 61 | 62 | namespace abb 63 | { 64 | namespace robot 65 | { 66 | 67 | /*********************************************************************************************************************** 68 | * Struct definitions: EGMControllerStopper::ParameterHandler 69 | */ 70 | 71 | EGMControllerStopper::ParameterHandler::ParameterHandler(ros::NodeHandle& nh) 72 | { 73 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_INIT, "Get ROS parameters (namespace '" << nh.getNamespace() << "')"); 74 | 75 | // Indicator for allowing no connection timeout during initialization. 76 | utilities::getParameter(nh, "no_service_timeout", no_service_timeout, false); 77 | 78 | // List of controllers that are allowed to keep running if EGM becomes inactive. 79 | utilities::getParameter(nh, "ros_control/controllers/ok_to_keep_running", controllers_ok_to_keep_running, {""}); 80 | } 81 | 82 | /*********************************************************************************************************************** 83 | * Class definitions: EGMControllerStopper 84 | */ 85 | 86 | /*********************************************************** 87 | * Primary methods 88 | */ 89 | 90 | EGMControllerStopper::EGMControllerStopper(ros::NodeHandle& nh_params, 91 | ros::NodeHandle& nh_msgs, 92 | ros::NodeHandle& nh_srvs) 93 | : 94 | parameters_{nh_params}, 95 | egm_states_subscriber_{nh_msgs.subscribe("egm_states", 1, &EGMControllerStopper::egmStatesCallback, this)}, 96 | list_controllers_client_{nh_srvs.serviceClient("list_controllers")}, 97 | switch_controllers_client_{nh_srvs.serviceClient("switch_controller")}, 98 | egm_previously_active_{false} 99 | { 100 | ROS_INFO_NAMED(ROS_LOG_INIT, "Initializing..."); 101 | 102 | // Prepare service request for switching ros_control controllers. 103 | switch_controllers_.request.strictness = controller_manager_msgs::SwitchController::Request::STRICT; 104 | 105 | //-------------------------------------------------------- 106 | // Wait for the ros_control controller manager services 107 | //-------------------------------------------------------- 108 | if(parameters_.no_service_timeout) 109 | { 110 | list_controllers_client_.waitForExistence(); 111 | switch_controllers_client_.waitForExistence(); 112 | } 113 | else 114 | { 115 | if(!list_controllers_client_.waitForExistence(ros::Duration(ROS_SERVICE_TIMEOUT))) 116 | { 117 | throw std::runtime_error{"Timed out while waiting for service '" + list_controllers_client_.getService() + "'"}; 118 | } 119 | 120 | if(!switch_controllers_client_.waitForExistence(ros::Duration(ROS_SERVICE_TIMEOUT))) 121 | { 122 | throw std::runtime_error{"Timed out while waiting for service '" + switch_controllers_client_.getService() + "'"}; 123 | } 124 | } 125 | 126 | ROS_INFO_NAMED(ROS_LOG_INIT, "Initialization succeeded, and the node is ready for use"); 127 | } 128 | 129 | /*********************************************************** 130 | * Auxiliary methods 131 | */ 132 | 133 | void EGMControllerStopper::egmStatesCallback(const abb_egm_msgs::EGMState::ConstPtr& message) 134 | { 135 | bool egm_currently_active{false}; 136 | 137 | // Check if any EGM channel is active. 138 | for(const auto& egm_channel : message->egm_channels) 139 | { 140 | if(egm_channel.active) egm_currently_active = true; 141 | } 142 | 143 | // Stop controllers that are not allowed to keep running if EGM has become inactive. 144 | if(egm_previously_active_ && !egm_currently_active) 145 | { 146 | checkAndStopControllers(); 147 | } 148 | 149 | egm_previously_active_ = egm_currently_active; 150 | } 151 | 152 | void EGMControllerStopper::checkAndStopControllers() 153 | { 154 | // Reset switch service request. 155 | switch_controllers_.request.start_controllers.clear(); 156 | switch_controllers_.request.stop_controllers.clear(); 157 | 158 | // Get the currenlty loaded ros_control controllers. 159 | if(!list_controllers_client_.call(list_controllers_)) 160 | { 161 | ROS_ERROR_NAMED(ROS_LOG_RUNTIME, "Failed to call service (to get list of currently loaded ros_control controllers)"); 162 | return; 163 | } 164 | 165 | // Check for running controllers, which are not allowed to keep running. 166 | for(const auto& controller : list_controllers_.response.controller) 167 | { 168 | if(controller.state == "running") 169 | { 170 | auto it = std::find(parameters_.controllers_ok_to_keep_running.begin(), 171 | parameters_.controllers_ok_to_keep_running.end(), 172 | controller.name); 173 | 174 | if(it == parameters_.controllers_ok_to_keep_running.end()) 175 | { 176 | switch_controllers_.request.stop_controllers.push_back(controller.name); 177 | } 178 | } 179 | } 180 | 181 | // Request controllers to be stopped. 182 | if(!switch_controllers_.request.stop_controllers.empty()) 183 | { 184 | ROS_WARN_STREAM_NAMED(ROS_LOG_RUNTIME, "EGM became inactive, stopping controllers not allowed to keep running: " << 185 | utilities::mapVectorToString(switch_controllers_.request.stop_controllers)); 186 | 187 | if(!switch_controllers_client_.call(switch_controllers_)) 188 | { 189 | ROS_ERROR_NAMED(ROS_LOG_RUNTIME, "Failed to call service (to stop ros_control controllers)"); 190 | return; 191 | } 192 | 193 | if(!switch_controllers_.response.ok) 194 | { 195 | ROS_ERROR_NAMED(ROS_LOG_RUNTIME, "Failed to stop ros_control controllers"); 196 | return; 197 | } 198 | } 199 | } 200 | 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.1) 2 | 3 | ######################################################################################################################## 4 | # Metadata 5 | ######################################################################################################################## 6 | # Read the package manifest. 7 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.xml" package_xml_str) 8 | 9 | # Extract project name. 10 | if(NOT package_xml_str MATCHES "([A-Za-z0-9_]+)") 11 | message(FATAL_ERROR "Could not parse project name from package manifest (aborting)") 12 | else() 13 | set(extracted_name ${CMAKE_MATCH_1}) 14 | endif() 15 | 16 | # Extract project version. 17 | if(NOT package_xml_str MATCHES "([0-9]+.[0-9]+.[0-9]+)") 18 | message(FATAL_ERROR "Could not parse project version from package manifest (aborting)") 19 | else() 20 | set(extracted_version ${CMAKE_MATCH_1}) 21 | endif() 22 | 23 | ######################################################################################################################## 24 | # CMake project 25 | ######################################################################################################################## 26 | project(${extracted_name} VERSION ${extracted_version} LANGUAGES CXX) 27 | 28 | #=========================================================== 29 | # Dependencies 30 | #=========================================================== 31 | #----------------------------- 32 | # ABB robot controller 33 | # communication package 34 | #----------------------------- 35 | find_package(abb_egm_rws_managers REQUIRED) 36 | 37 | # Extract include directories, because some subsequent 38 | # catkin packages can't seem to build without this. 39 | get_target_property(abb_libegm_INCLUDE_DIRS ${abb_libegm_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 40 | get_target_property(abb_librws_INCLUDE_DIRS ${abb_librws_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 41 | get_target_property(abb_egm_rws_managers_INCLUDE_DIRS ${abb_egm_rws_managers_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES) 42 | 43 | #----------------------------- 44 | # Catkin packages 45 | #----------------------------- 46 | find_package(catkin REQUIRED 47 | COMPONENTS 48 | abb_robot_cpp_utilities 49 | abb_robot_msgs 50 | controller_manager 51 | controller_manager_msgs 52 | hardware_interface 53 | roscpp 54 | ) 55 | 56 | #=========================================================== 57 | # Catkin package specific configurations 58 | #=========================================================== 59 | catkin_package( 60 | INCLUDE_DIRS 61 | include 62 | LIBRARIES 63 | ${PROJECT_NAME}_hardware_interface 64 | ${PROJECT_NAME}_controller_stopper 65 | CATKIN_DEPENDS 66 | abb_robot_cpp_utilities 67 | abb_robot_msgs 68 | controller_manager 69 | controller_manager_msgs 70 | hardware_interface 71 | roscpp 72 | DEPENDS 73 | abb_egm_rws_managers 74 | abb_libegm 75 | abb_librws 76 | Boost 77 | Poco 78 | Protobuf 79 | ) 80 | 81 | #=========================================================== 82 | # Settings 83 | #=========================================================== 84 | if(NOT DEFINED BUILD_SHARED_LIBS) 85 | set(BUILD_SHARED_LIBS ON) 86 | endif() 87 | 88 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 89 | message(STATUS "${PROJECT_NAME}: Defaulting build type to RelWithDebInfo") 90 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 91 | endif() 92 | 93 | #=========================================================== 94 | # Build targets (for the ros_control hardware interface) 95 | #=========================================================== 96 | set(target_name ${PROJECT_NAME}_hardware_interface) 97 | 98 | #----------------------------- 99 | # Library target 100 | #----------------------------- 101 | set( 102 | src_files 103 | src/egm_hardware_interface.cpp 104 | ) 105 | 106 | add_library(${target_name} ${src_files}) 107 | 108 | target_include_directories(${target_name} PUBLIC 109 | "$" 110 | "$/include>" 111 | "${catkin_INCLUDE_DIRS}" 112 | ) 113 | 114 | target_link_libraries(${target_name} PUBLIC 115 | abb_egm_rws_managers::abb_egm_rws_managers 116 | ${catkin_LIBRARIES} 117 | ) 118 | 119 | target_compile_features(${target_name} PRIVATE cxx_std_14) 120 | 121 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 122 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 123 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 124 | target_compile_options(${target_name} PRIVATE /W4) 125 | endif() 126 | 127 | #----------------------------- 128 | # Executable target 129 | #----------------------------- 130 | set( 131 | src_files 132 | src/egm_hardware_interface_main.cpp 133 | ) 134 | 135 | add_executable(${target_name}_exe ${src_files}) 136 | 137 | target_include_directories(${target_name}_exe PRIVATE 138 | "${catkin_INCLUDE_DIRS}" 139 | ) 140 | 141 | target_link_libraries(${target_name}_exe PRIVATE 142 | ${catkin_LIBRARIES} 143 | ${target_name} 144 | ) 145 | 146 | target_compile_features(${target_name}_exe PRIVATE cxx_std_14) 147 | 148 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 149 | target_compile_options(${target_name}_exe PRIVATE -Wall -Wextra -Wpedantic) 150 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 151 | target_compile_options(${target_name}_exe PRIVATE /W4) 152 | endif() 153 | 154 | set_target_properties(${target_name}_exe 155 | PROPERTIES 156 | OUTPUT_NAME "egm_hardware_interface" 157 | ) 158 | 159 | #=========================================================== 160 | # Build targets (for the stopper of ros_control controllers) 161 | #=========================================================== 162 | set(target_name ${PROJECT_NAME}_controller_stopper) 163 | 164 | #----------------------------- 165 | # Library target 166 | #----------------------------- 167 | set( 168 | src_files 169 | src/egm_controller_stopper.cpp 170 | ) 171 | 172 | add_library(${target_name} ${src_files}) 173 | 174 | target_include_directories(${target_name} PUBLIC 175 | "$" 176 | "$/include>" 177 | "${catkin_INCLUDE_DIRS}" 178 | ) 179 | 180 | target_link_libraries(${target_name} PUBLIC 181 | ${catkin_LIBRARIES} 182 | ) 183 | 184 | target_compile_features(${target_name} PRIVATE cxx_std_14) 185 | 186 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 187 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic) 188 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 189 | target_compile_options(${target_name} PRIVATE /W4) 190 | endif() 191 | 192 | #----------------------------- 193 | # Executable target 194 | #----------------------------- 195 | set( 196 | src_files 197 | src/egm_controller_stopper_main.cpp 198 | ) 199 | 200 | add_executable(${target_name}_exe ${src_files}) 201 | 202 | target_include_directories(${target_name}_exe PRIVATE 203 | "${catkin_INCLUDE_DIRS}" 204 | ) 205 | 206 | target_link_libraries(${target_name}_exe PRIVATE 207 | ${catkin_LIBRARIES} 208 | ${target_name} 209 | ) 210 | 211 | target_compile_features(${target_name}_exe PRIVATE cxx_std_14) 212 | 213 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 214 | target_compile_options(${target_name}_exe PRIVATE -Wall -Wextra -Wpedantic) 215 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 216 | target_compile_options(${target_name}_exe PRIVATE /W4) 217 | endif() 218 | 219 | set_target_properties(${target_name}_exe 220 | PROPERTIES 221 | OUTPUT_NAME "egm_controller_stopper" 222 | ) 223 | 224 | #=========================================================== 225 | # Install 226 | #=========================================================== 227 | install( 228 | TARGETS 229 | ${PROJECT_NAME}_hardware_interface 230 | ${PROJECT_NAME}_hardware_interface_exe 231 | ${PROJECT_NAME}_controller_stopper 232 | ${PROJECT_NAME}_controller_stopper_exe 233 | ARCHIVE DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 234 | LIBRARY DESTINATION "${CATKIN_PACKAGE_LIB_DESTINATION}" 235 | RUNTIME DESTINATION "${CATKIN_PACKAGE_BIN_DESTINATION}" 236 | ) 237 | 238 | install( 239 | DIRECTORY include/${PROJECT_NAME}/ 240 | DESTINATION "${CATKIN_PACKAGE_INCLUDE_DESTINATION}" 241 | ) 242 | 243 | install( 244 | DIRECTORY config launch 245 | DESTINATION "${CATKIN_PACKAGE_SHARE_DESTINATION}" 246 | ) 247 | -------------------------------------------------------------------------------- /abb_robot_cpp_utilities/include/abb_robot_cpp_utilities/mapping.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_ROBOT_CPP_UTILITIES_MAPPING_H 38 | #define ABB_ROBOT_CPP_UTILITIES_MAPPING_H 39 | 40 | #include 41 | 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | #include 48 | 49 | namespace abb 50 | { 51 | namespace robot 52 | { 53 | namespace utilities 54 | { 55 | 56 | /** 57 | * \brief Maps RAPID task execution state to ROS representation. 58 | * 59 | * \param state to map. 60 | * 61 | * \return uint8_t containing the mapped state. 62 | */ 63 | uint8_t map(const rws::RWSInterface::RAPIDTaskExecutionState state); 64 | 65 | /** 66 | * \brief Maps RobotWare StateMachine Add-In state to ROS representation. 67 | * 68 | * \param state to map. 69 | * 70 | * \return uint8_t containing the mapped state. 71 | */ 72 | uint8_t mapStateMachineState(const rws::RAPIDNum& state); 73 | 74 | /** 75 | * \brief Maps RobotWare StateMachine Add-In EGM action to ROS representation. 76 | * 77 | * \param action to map. 78 | * 79 | * \return uint8_t containing the mapped state. 80 | */ 81 | uint8_t mapStateMachineEGMAction(const rws::RAPIDNum& action); 82 | 83 | /** 84 | * \brief Maps RobotWare StateMachine Add-In SmartGripper command to RWS representation. 85 | * 86 | * \param command to map. 87 | * 88 | * \return unsigned int containing the mapped command. 89 | * 90 | * \throw std::runtime_error if the command is unknown. 91 | */ 92 | unsigned int mapStateMachineSGCommand(const unsigned int command); 93 | 94 | /** 95 | * \brief Maps a RAPID 'pos' data type from RWS to ROS representation. 96 | * 97 | * \param rws_pos to map. 98 | * 99 | * \return abb_rapid_msgs::Pos containing the mapped data. 100 | */ 101 | abb_rapid_msgs::Pos map(const rws::Pos& rws_pos); 102 | 103 | /** 104 | * \brief Maps a RAPID 'orient' data type from RWS to ROS representation. 105 | * 106 | * \param rws_orient to map. 107 | * 108 | * \return abb_rapid_msgs::Orient containing the mapped data. 109 | */ 110 | abb_rapid_msgs::Orient map(const rws::Orient& rws_orient); 111 | 112 | /** 113 | * \brief Maps a RAPID 'pose' data type from RWS to ROS representation. 114 | * 115 | * \param rws_pose to map. 116 | * 117 | * \return abb_rapid_msgs::Pose containing the mapped data. 118 | */ 119 | abb_rapid_msgs::Pose map(const rws::Pose& rws_pose); 120 | 121 | /** 122 | * \brief Maps a RAPID 'loaddata' data type from RWS to ROS representation. 123 | * 124 | * \param rws_loaddata to map. 125 | * 126 | * \return abb_rapid_msgs::LoadData containing the mapped data. 127 | */ 128 | abb_rapid_msgs::LoadData map(const rws::LoadData& rws_loaddata); 129 | 130 | /** 131 | * \brief Maps a RAPID 'tooldata' data type from RWS to ROS representation. 132 | * 133 | * \param rws_tooldata to map. 134 | * 135 | * \return abb_rapid_msgs::ToolData containing the mapped data. 136 | */ 137 | abb_rapid_msgs::ToolData map(const rws::ToolData& rws_tooldata); 138 | 139 | /** 140 | * \brief Maps a RAPID 'wobjdata' data type from RWS to ROS representation. 141 | * 142 | * \param rws_wobjdata to map. 143 | * 144 | * \return abb_rapid_msgs::WObjData containing the mapped data. 145 | */ 146 | abb_rapid_msgs::WObjData map(const rws::WObjData& rws_wobjdata); 147 | 148 | /** 149 | * \brief Maps a RobotWare StateMachine Add-In RAPID 'EGMSettings' data type from RWS to ROS representation. 150 | * 151 | * \param rws_egm_settings to map. 152 | * 153 | * \return abb_rapid_sm_addin_msgs::EGMSettings containing the mapped data. 154 | */ 155 | abb_rapid_sm_addin_msgs::EGMSettings map(const rws::RWSStateMachineInterface::EGMSettings& rws_egm_settings); 156 | 157 | /** 158 | * \brief Maps a RAPID 'pos' data type from ROS to RWS representation. 159 | * 160 | * \param ros_pos to map. 161 | * 162 | * \return rws::Pos containing the mapped data. 163 | */ 164 | rws::Pos map(const abb_rapid_msgs::Pos& ros_pos); 165 | 166 | /** 167 | * \brief Maps a RAPID 'orient' data type from ROS to RWS representation. 168 | * 169 | * \param ros_orient to map. 170 | * 171 | * \return rws::Orient containing the mapped data. 172 | */ 173 | rws::Orient map(const abb_rapid_msgs::Orient& ros_orient); 174 | 175 | /** 176 | * \brief Maps a RAPID 'pose' data type from ROS to RWS representation. 177 | * 178 | * \param ros_pose to map. 179 | * 180 | * \return rws::Pose containing the mapped data. 181 | */ 182 | rws::Pose map(const abb_rapid_msgs::Pose& ros_pose); 183 | 184 | /** 185 | * \brief Maps a RAPID 'loaddata' data type from ROS to RWS representation. 186 | * 187 | * \param ros_loaddata to map. 188 | * 189 | * \return rws::LoadData containing the mapped data. 190 | */ 191 | rws::LoadData map(const abb_rapid_msgs::LoadData& ros_loaddata); 192 | 193 | /** 194 | * \brief Maps a RAPID 'tooldata' data type from ROS to RWS representation. 195 | * 196 | * \param ros_tooldata to map. 197 | * 198 | * \return rws::ToolData containing the mapped data. 199 | */ 200 | rws::ToolData map(const abb_rapid_msgs::ToolData& ros_tooldata); 201 | 202 | /** 203 | * \brief Maps a RAPID 'wobjdata' data type from ROS to RWS representation. 204 | * 205 | * \param ros_wobjdata to map. 206 | * 207 | * \return rws::WObjData containing the mapped data. 208 | */ 209 | rws::WObjData map(const abb_rapid_msgs::WObjData& ros_wobjdata); 210 | 211 | /** 212 | * \brief Maps a RobotWare StateMachine Add-In RAPID 'EGMSettings' data type from ROS to RWS representation. 213 | * 214 | * \param ros_egm_settings to map. 215 | * 216 | * \return rws::RWSStateMachineInterface::EGMSettings containing the mapped data. 217 | */ 218 | rws::RWSStateMachineInterface::EGMSettings map(const abb_rapid_sm_addin_msgs::EGMSettings& ros_egm_settings); 219 | 220 | /** 221 | * \brief Maps EGM state to ROS representation. 222 | * 223 | * \param state to map. 224 | * 225 | * \return uint8_t containing the mapped state. 226 | */ 227 | uint8_t map(const egm::wrapper::Status::EGMState state); 228 | 229 | /** 230 | * \brief Maps motor state to ROS representation. 231 | * 232 | * \param state to map. 233 | * 234 | * \return uint8_t containing the mapped state. 235 | */ 236 | uint8_t map(const egm::wrapper::Status::MotorState state); 237 | 238 | /** 239 | * \brief Maps RAPID execution state to ROS representation. 240 | * 241 | * \param state to map. 242 | * 243 | * \return uint8_t containing the mapped state. 244 | */ 245 | uint8_t map(const egm::wrapper::Status::RAPIDExecutionState rapid_execution_state); 246 | 247 | /** 248 | * \brief Maps a vector to a string (e.g. for logging). 249 | * 250 | * \param vector to map. 251 | * 252 | * \return std::string of the mapped vector. 253 | * 254 | * \throw std::runtime if the mapping failed. 255 | */ 256 | template 257 | std::string mapVectorToString(const std::vector& vector); 258 | 259 | } 260 | } 261 | } 262 | 263 | #endif 264 | -------------------------------------------------------------------------------- /abb_robot_bringup_examples/README.md: -------------------------------------------------------------------------------- 1 | # abb_robot_bringup_examples 2 | 3 | [![license - bsd 3 clause](https://img.shields.io/:license-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 4 | [![support level: vendor](https://img.shields.io/badge/support%20level-vendor-brightgreen.svg)](http://rosindustrial.org/news/2016/10/7/better-supporting-a-growing-ros-industrial-software-platform) 5 | 6 | **Please note that this package has not been productized, and that academia is the intended audience.**\ 7 | **The package is provided "as-is", and as such no more than limited support can be expected.** 8 | 9 | ## Overview 10 | 11 | The ROS nodes included in [abb_robot_driver](https://github.com/ros-industrial/abb_robot_driver) can only interact with ABB robots that are supported by these interfaces: 12 | 13 | - *Robot Web Services* (`RWS`) `1.0`: 14 | - Available in `IRC5` controllers with `RobotWare 6` systems. 15 | - `RWS` is independent of robot type. 16 | - *Externally Guided Motion* (`EGM`): 17 | - Requires the `RobotWare 6` option *Externally Guided Motion* (`689-1`). 18 | - `EGM` is only available for `6` and `7` axes robots. 19 | 20 | The following examples illustrates how to bringup the ROS nodes for a few different use cases, namely: 21 | 22 | | Example | Description | 23 | | --- | --- | 24 | | [ex1_rws_only](#example-1-ex1_rws_only) | Using only `RWS` components, e.g. to listen for general system states and restarting `RAPID` program execution. | 25 | | [ex2_rws_and_egm_6axis_robot](#example-2-ex2_rws_and_egm_6axis_robot) | Using both `RWS` and `EGM` components (*with a 6-axes robot*), i.a. for starting an `EGM` session and publishing joint velocity commands. | 26 | | [ex3_rws_and_egm_yumi_robot](#example-3-ex3_rws_and_egm_yumi_robot) | Using both `RWS` and `EGM` components (*with a `YuMi` robot*), i.a. for starting an `EGM` session and publishing joint velocity commands. | 27 | 28 | Please inspect the files in the [launch](launch) and [config](config) folders for more details about respective example. 29 | 30 | ## Examples 31 | 32 | **Please note that it is recommended to try out the examples against `RobotStudio` simulations before testing with real robots.** 33 | 34 | ### Example 1: "ex1_rws_only" 35 | 36 | - The `RWS` components are independent of robot type. 37 | 38 | #### Steps 39 | 40 | 1. Start 3 terminals. 41 | 2. **[Terminal 1]** Launch the example: 42 | ``` 43 | roslaunch abb_robot_bringup_examples ex1_rws_only.launch robot_ip:= 44 | ``` 45 | 3. **[Terminal 2]** Use `rostopic` to, for example, list available topics and then listen for general robot controller states: 46 | ``` 47 | rostopic list 48 | rostopic echo -c /rws/system_states 49 | ``` 50 | 4. **[Terminal 3]** Use `rosservice` to, for example, list available services and then stop, reset and start the `RAPID` execution: 51 | ``` 52 | rosservice list 53 | rosservice call /rws/stop_rapid "{}" 54 | rosservice call /rws/pp_to_main "{}" 55 | rosservice call /rws/start_rapid "{}" 56 | ``` 57 | 58 | --- 59 | 60 | ### Example 2: "ex2_rws_and_egm_6axis_robot" 61 | 62 | - **`EGM` usage is only recommended for advanced users:** 63 | - **Please be careful when sending motion commands! The robot will respond immediately.** 64 | - Assumptions: 65 | - A 6-axes robot is used. 66 | - The `EGM` `RobotWare` option is present in the robot controller system. 67 | - The `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1) was used when installing the robot controller system. 68 | - Impactful `EGM` `RAPID` arguments: 69 | - The `\MaxSpeedDeviation` argument of `EGMActJoint` (*e.g. limits `EGM` references on the robot controller side*). 70 | - The `\PosCorrGain` argument of `EGMRunJoint` (*e.g. needs to be `0` for pure velocity control*). 71 | - The `ros_control` controller, which command motions, is only allowed to start if an `EGM` session is active. 72 | 73 | #### Steps 74 | 75 | 1. Start 4 terminals. 76 | 2. **[Terminal 1]** Launch the example: 77 | ``` 78 | roslaunch abb_robot_bringup_examples ex2_rws_and_egm_6axis_robot.launch robot_ip:= 79 | ``` 80 | 3. **[Terminal 2]** Use `rostopic` to listen for `EGM` channel states: 81 | ``` 82 | rostopic echo -c /egm/egm_states 83 | ``` 84 | 4. **[Terminal 3]** Use `rosservice` to restart `RAPID`, and then start an `EGM` session: 85 | ``` 86 | rosservice call /rws/stop_rapid "{}" 87 | rosservice call /rws/pp_to_main "{}" 88 | rosservice call /rws/start_rapid "{}" 89 | rosservice call /rws/sm_addin/start_egm_joint "{}" 90 | ``` 91 | 5. **[Terminal 3]** Use `rosservice` to start the `ros_control` command controller (*requires a running `EGM` session*): 92 | ``` 93 | rosservice call /egm/controller_manager/switch_controller "start_controllers: [joint_group_velocity_controller] 94 | stop_controllers: [''] 95 | strictness: 1 96 | start_asap: false 97 | timeout: 0.0" 98 | ``` 99 | 6. **[Terminal 4]** Use `rostopic` to publish velocity commands for the sixth joint: 100 | ``` 101 | rostopic pub /egm/joint_group_velocity_controller/command std_msgs/Float64MultiArray "data: [0,0,0,0,0,0.1]" 102 | ``` 103 | 7. **[Terminal 3]** Use `rosservice` to stop the `EGM` session: 104 | ``` 105 | rosservice call /rws/sm_addin/stop_egm "{}" 106 | ``` 107 | 108 | --- 109 | 110 | ### Example 3: "ex3_rws_and_egm_yumi_robot" 111 | 112 | - **`EGM` usage is only recommended for advanced users:** 113 | - **Please be careful when sending motion commands! The robot will respond immediately.** 114 | - Assumptions: 115 | - A `YuMi` robot is used. 116 | - The `EGM` `RobotWare` option is present in the robot controller system. 117 | - The `RobotWare` [StateMachine Add-In](https://robotapps.robotstudio.com/#/viewApp/c163de01-792e-4892-a290-37dbe050b6e1) was used when installing the robot controller system. 118 | - Impactful `EGM` `RAPID` arguments: 119 | - The `\MaxSpeedDeviation` argument of `EGMActJoint` (*e.g. limits `EGM` references on the robot controller side*). 120 | - The `\PosCorrGain` argument of `EGMRunJoint` (*e.g. needs to be `0` for pure velocity control*). 121 | - The `ros_control` controller, which command motions, is only allowed to start if an `EGM` session is active. 122 | - The ROS nodes are launched in an separate namespace `/yumi` (*i.e. it is good practice to do so*): 123 | - Inspect the example launch file, and corresponding configurations files, to see the impact of a separate namespace. 124 | 125 | #### Steps 126 | 127 | 1. Start 4 terminals. 128 | 2. **[Terminal 1]** Launch the example: 129 | ``` 130 | roslaunch abb_robot_bringup_examples ex3_rws_and_egm_yumi_robot.launch robot_ip:= 131 | ``` 132 | 3. **[Terminal 2]** Use `rostopic` to listen for `EGM` channel states: 133 | ``` 134 | rostopic echo -c /yumi/egm/egm_states 135 | ``` 136 | 4. **[Terminal 3]** Use `rosservice` to restart `RAPID`, and then start an `EGM` session: 137 | ``` 138 | rosservice call /yumi/rws/stop_rapid "{}" 139 | rosservice call /yumi/rws/pp_to_main "{}" 140 | rosservice call /yumi/rws/start_rapid "{}" 141 | rosservice call /yumi/rws/sm_addin/start_egm_joint "{}" 142 | ``` 143 | 5. **[Terminal 3]** Use `rosservice` to start the `ros_control` command controller (*requires a running `EGM` session*): 144 | ``` 145 | rosservice call /yumi/egm/controller_manager/switch_controller "start_controllers: [joint_group_velocity_controller] 146 | stop_controllers: [''] 147 | strictness: 1 148 | start_asap: false 149 | timeout: 0.0" 150 | ``` 151 | 6. **[Terminal 4]** Use `rostopic` to publish velocity commands for the seventh joint (on each arm): 152 | ``` 153 | rostopic pub /yumi/egm/joint_group_velocity_controller/command std_msgs/Float64MultiArray "data: [0,0,0,0,0,0,-0.1,0,0,0,0,0,0,0.1]" 154 | ``` 155 | 7. **[Terminal 3]** Use `rosservice` to stop the `EGM` session: 156 | ``` 157 | rosservice call /yumi/rws/sm_addin/stop_egm "{}" 158 | ``` 159 | 160 | ## Acknowledgements 161 | 162 | ### ROSIN Project 163 | 164 |

165 | 166 | rosin_logo 167 | 168 | The core development has been made within the European Union's Horizon 2020 project: ROSIN - ROS-Industrial Quality-Assured Robot Software Components (see http://rosin-project.eu for more info). 169 |

170 | eu_flag 171 | The ROSIN project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement no. 732287. 172 |

173 | 174 | *The opinions expressed here reflects only the author's view and reflects in no way the European Commission's opinions. The European Commission is not responsible for any use that may be made of the contained information.* 175 | 176 | ### Special Thanks 177 | 178 | Special thanks to [gavanderhoorn](https://github.com/gavanderhoorn) for guidance with open-source practices and conventions. 179 | -------------------------------------------------------------------------------- /abb_egm_hardware_interface/include/abb_egm_hardware_interface/egm_hardware_interface.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #ifndef ABB_EGM_HARDWARE_INTERFACE_EGM_HARDWARE_INTERFACE_H 38 | #define ABB_EGM_HARDWARE_INTERFACE_EGM_HARDWARE_INTERFACE_H 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | 55 | #include 56 | 57 | #include "egm_state_interface.h" 58 | 59 | namespace abb 60 | { 61 | namespace robot 62 | { 63 | 64 | /** 65 | * \brief Hardware interface towards ABB robot controllers supporting the Externally Guided Motion (EGM) interface. 66 | */ 67 | class EGMHardwareInterface : public hardware_interface::RobotHW 68 | { 69 | public: 70 | /** 71 | * \brief Creates a hardware interface for interacting with an ABB robot controller via EGM. 72 | */ 73 | EGMHardwareInterface(); 74 | 75 | /** 76 | * \brief Initializes the hardware interface. 77 | * 78 | * \param root_nh node handle (in the namespace where ROS interfaces should operate in during runtime). 79 | * \param robot_hw_nh node handle (in the namespace where ROS parameters should be read from during initialization). 80 | * 81 | * \return bool true if the initialization succeeded. 82 | */ 83 | bool init(ros::NodeHandle& root_nh, ros::NodeHandle& robot_hw_nh); 84 | 85 | /** 86 | * \brief Prepares (in non-realtime) to start and stop (ros_control) controllers. 87 | * 88 | * \param start_list specifying controllers to start. 89 | * \param stop_list specifying controllers to stop. 90 | * 91 | * \return bool true if is ok to start and stop the controllers. 92 | */ 93 | bool prepareSwitch(const std::list& start_list, 94 | const std::list& stop_list); 95 | 96 | /** 97 | * \brief Waits for a message from the hardware. 98 | * 99 | * \return ros::Duration it took when waiting for the message. 100 | */ 101 | ros::Duration waitForMessage(); 102 | 103 | /** 104 | * \brief Reads a message from the hardware. 105 | * 106 | * \param time specifying the current time. 107 | * \param period since the last call. 108 | * 109 | * \throw std::runtime_error if the hardware interface is uninitialized. 110 | */ 111 | void read(const ros::Time& time, const ros::Duration& period); 112 | 113 | /** 114 | * \brief Writes a command to the hardware. 115 | * 116 | * \param time specifying the current time. 117 | * \param period since the last call. 118 | * 119 | * \throw std::runtime_error if the hardware interface is uninitialized. 120 | */ 121 | void write(const ros::Time& time, const ros::Duration& period); 122 | 123 | /** 124 | * \brief Checks if a reset of (ros_control) controllers is needed. 125 | * 126 | * This method assumes that the reset will be performed and the task is passed to the calling code. 127 | * 128 | * \return bool true if a reset is needed. 129 | */ 130 | bool resetNeeded(); 131 | 132 | private: 133 | /** 134 | * \brief Parameters for a single EGM channel. 135 | */ 136 | struct EGMChannelParameters 137 | { 138 | /** 139 | * \brief Name of the channel. 140 | */ 141 | std::string name; 142 | 143 | /** 144 | * \brief Port number used by the channel. 145 | */ 146 | unsigned short port_number; 147 | 148 | /** 149 | * \brief Mechanical unit group that is expected to use the channel. 150 | */ 151 | std::string mech_unit_group; 152 | }; 153 | 154 | /** 155 | * \brief Initializes the robot contoller description by calling a ROS service to get the description in text format. 156 | * 157 | * \param nh for the node handle to use when calling the ROS service. 158 | * 159 | * \return bool true if the initialization succeeded. 160 | */ 161 | bool initializeRobotControllerDescription(ros::NodeHandle& nh); 162 | 163 | /** 164 | * \brief Initializes the EGM channel parameters by collecting them from the ROS parameter server. 165 | * 166 | * \param nh for the node handle to use when reading the ROS parameters. 167 | * 168 | * \return bool true if the initialization succeeded. 169 | */ 170 | bool initializeEGMChannelParameters(ros::NodeHandle& nh); 171 | 172 | /** 173 | * \brief Initializes the EGM manager. 174 | * 175 | * \return bool true if the initialization succeeded. 176 | */ 177 | bool initializeEGMManager(); 178 | 179 | /** 180 | * \brief Initializes components for 'ros_control' interaction. 181 | * 182 | * \param nh specifying a node handle to use. 183 | */ 184 | void initializeROSControlLayer(ros::NodeHandle& nh); 185 | 186 | /** 187 | * \brief Manager for handling EGM communication with the robot controller. 188 | */ 189 | std::unique_ptr p_egm_manager_; 190 | 191 | /** 192 | * \brief Interface for handling the state data concerning the EGM channels. 193 | */ 194 | EGMStateInterface egm_state_interface_; 195 | 196 | /** 197 | * \brief Interface for handling all joint state resources. 198 | */ 199 | hardware_interface::JointStateInterface joint_state_interface_; 200 | 201 | /** 202 | * \brief Interface for handling all (controllable) joint position resources. 203 | */ 204 | hardware_interface::PositionJointInterface joint_position_interface_; 205 | 206 | /** 207 | * \brief Interface for handling all (controllable) joint velocity resources. 208 | */ 209 | hardware_interface::VelocityJointInterface joint_velocity_interface_; 210 | 211 | /** 212 | * \brief Interface for handling all (controllable) joint position and velocity resources. 213 | */ 214 | hardware_interface::PosVelJointInterface joint_position_velocity_interface_; 215 | 216 | /** 217 | * \brief Interface for applying soft limits to (controllale) joint position resources. 218 | */ 219 | joint_limits_interface::PositionJointSoftLimitsInterface joint_position_soft_limits_interface_; 220 | 221 | /** 222 | * \brief Interface for applying soft limits to (controllale) joint velocity resources. 223 | */ 224 | joint_limits_interface::VelocityJointSoftLimitsInterface joint_velocity_soft_limits_interface_; 225 | 226 | /** 227 | * \brief Description of the connected robot controller. 228 | */ 229 | RobotControllerDescription robot_controller_description_; 230 | 231 | /** 232 | * \brief EGM channel parameters collected from the ROS parameter server. 233 | */ 234 | std::vector egm_channel_parameters_; 235 | 236 | /** 237 | * \brief Indicator for if EGM is active. 238 | */ 239 | std::atomic_bool egm_active_; 240 | 241 | /** 242 | * \brief Indicator for if an EGM client is in running state (i.e. listening for motion references). 243 | */ 244 | std::atomic_bool egm_client_running_; 245 | 246 | /** 247 | * \brief Indicator for if a reset of (ros_control) controllers is needed. 248 | */ 249 | std::atomic_bool reset_of_ros_control_controllers_needed_; 250 | 251 | /** 252 | * \brief Motion data for each mechanical unit defined in the connected robot controller. 253 | * 254 | * For example, joint states and commands. 255 | */ 256 | MotionData motion_data_; 257 | 258 | /** 259 | * \brief Indicator for if a log message should be printed when feedback has been received. 260 | */ 261 | bool print_feedback_received_; 262 | 263 | /** 264 | * \brief Indicator for if any ros_control controller has been started. 265 | */ 266 | bool any_controller_started_; 267 | 268 | /** 269 | * \brief List of user specified ros_control controllers that are always ok to start. 270 | * 271 | * For example, when the EGM session is inactive, or the EGM client is not in running state. 272 | */ 273 | std::vector controllers_always_ok_to_start_; 274 | }; 275 | 276 | } 277 | } 278 | 279 | #endif 280 | -------------------------------------------------------------------------------- /abb_rws_state_publisher/src/rws_state_publisher.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * Copyright (c) 2020, ABB Schweiz AG 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with 7 | * or without modification, are permitted provided that 8 | * the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the 11 | * above copyright notice, this list of conditions 12 | * and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the 14 | * above copyright notice, this list of conditions 15 | * and the following disclaimer in the documentation 16 | * and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of ABB nor the names of its 19 | * contributors may be used to endorse or promote 20 | * products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *********************************************************************************************************************** 35 | */ 36 | 37 | #include 38 | 39 | #include 40 | 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "abb_rws_state_publisher/rws_state_publisher.h" 50 | 51 | namespace 52 | { 53 | /** 54 | * \brief Name for ROS logging in the 'init' context. 55 | */ 56 | constexpr char ROS_LOG_INIT[]{"init"}; 57 | 58 | /** 59 | * \brief Name for ROS logging in the 'publisher' context. 60 | */ 61 | constexpr char ROS_LOG_PUBLISHER[]{"publisher"}; 62 | 63 | /** 64 | * \brief Time [s] for throttled ROS logging. 65 | */ 66 | constexpr double THROTTLE_TIME{10.0}; 67 | } 68 | 69 | namespace abb 70 | { 71 | namespace robot 72 | { 73 | 74 | /*********************************************************************************************************************** 75 | * Struct definitions: RWSServiceProvider::ParameterHandler 76 | */ 77 | 78 | RWSStatePublisher::ParameterHandler::ParameterHandler(ros::NodeHandle& nh) 79 | : 80 | robot_port{0}, 81 | polling_rate{0.0} 82 | { 83 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_INIT, "Get ROS parameters (namespace '" << nh.getNamespace() << "')"); 84 | 85 | // IP address. 86 | utilities::getParameter(nh, "robot_ip", robot_ip, std::string{"127.0.0.1"}); 87 | utilities::verifyIPAddress(robot_ip); 88 | 89 | // Port number. 90 | utilities::getParameter(nh, "robot_port", robot_port, 80); 91 | utilities::verifyPortNumber(robot_port); 92 | 93 | // Robot controller nickname/identifier. 94 | utilities::getParameter(nh, "robot_nickname", robot_nickname, std::string{}); 95 | 96 | // Indicator for allowing no connection timeout during initialization. 97 | utilities::getParameter(nh, "no_connection_timeout", no_connection_timeout, false); 98 | 99 | // Polling rate. 100 | utilities::getParameter(nh, "polling_rate", polling_rate, 5.0); 101 | utilities::verifyRate(polling_rate); 102 | } 103 | 104 | /*********************************************************************************************************************** 105 | * Class definitions: RWSStatePublisher 106 | */ 107 | 108 | /*********************************************************** 109 | * Primary methods 110 | */ 111 | 112 | RWSStatePublisher::RWSStatePublisher(ros::NodeHandle& nh_params, ros::NodeHandle& nh_msgs) 113 | : 114 | parameters_{nh_params}, 115 | rws_manager_{parameters_.robot_ip, 116 | static_cast(parameters_.robot_port), 117 | rws::SystemConstants::General::DEFAULT_USERNAME, 118 | rws::SystemConstants::General::DEFAULT_PASSWORD}, 119 | polling_rate_{parameters_.polling_rate} 120 | { 121 | ROS_INFO_NAMED(ROS_LOG_INIT, "Initializing..."); 122 | 123 | //-------------------------------------------------------- 124 | // Connect to the robot controller 125 | //-------------------------------------------------------- 126 | robot_controller_description_ = utilities::establishRWSConnection(rws_manager_, 127 | parameters_.robot_nickname, 128 | parameters_.no_connection_timeout); 129 | 130 | ROS_DEBUG_STREAM_NAMED(ROS_LOG_INIT, "Robot controller description:\n" << summaryText(robot_controller_description_)); 131 | 132 | utilities::verifyRobotWareVersion(robot_controller_description_.header().robot_ware_version()); 133 | initializeMotionData(motion_data_, robot_controller_description_); 134 | 135 | //-------------------------------------------------------- 136 | // Advertise publishers 137 | //-------------------------------------------------------- 138 | joint_state_publisher_ = nh_msgs.advertise("joint_states", 1); 139 | system_state_publisher_ = nh_msgs.advertise("system_states", 1); 140 | 141 | if(utilities::verifyStateMachineAddInPresence(robot_controller_description_.system_indicators())) 142 | { 143 | sm_runtime_state_publisher_ = nh_msgs.advertise("sm_addin/runtime_states",1); 144 | } 145 | 146 | //-------------------------------------------------------- 147 | // Timer 148 | //-------------------------------------------------------- 149 | polling_timer_ = nh_msgs.createTimer(polling_rate_, &RWSStatePublisher::pollingTimerCallback, this); 150 | 151 | ROS_INFO_NAMED(ROS_LOG_INIT, "Initialization succeeded, and the node is ready for use"); 152 | } 153 | 154 | /*********************************************************** 155 | * Auxiliary methods 156 | */ 157 | 158 | void RWSStatePublisher::pollingTimerCallback(const ros::TimerEvent& event) 159 | { 160 | (void) event; 161 | 162 | try 163 | { 164 | rws_manager_.collectAndUpdateRuntimeData(system_state_data_, motion_data_); 165 | } 166 | catch(const std::runtime_error& exception) 167 | { 168 | ROS_WARN_STREAM_THROTTLE_NAMED(THROTTLE_TIME, ROS_LOG_INIT, 169 | "Periodic polling of runtime data via RWS failed with '" << exception.what() << 170 | "' (will try again later)"); 171 | } 172 | 173 | //-------------------------------------------------------- 174 | // Parse joint states 175 | //-------------------------------------------------------- 176 | sensor_msgs::JointState joint_state_message{}; 177 | for(auto& group : motion_data_.groups) 178 | { 179 | for(auto& unit : group.units) 180 | { 181 | for(auto& joint : unit.joints) 182 | { 183 | joint_state_message.name.push_back(joint.name); 184 | joint_state_message.position.push_back(joint.state.position); 185 | } 186 | } 187 | } 188 | 189 | //-------------------------------------------------------- 190 | // Parse general system states 191 | //-------------------------------------------------------- 192 | abb_robot_msgs::SystemState system_state_message{}; 193 | system_state_message.motors_on = system_state_data_.motors_on.isTrue(); 194 | system_state_message.auto_mode = system_state_data_.auto_mode.isTrue(); 195 | system_state_message.rapid_running = system_state_data_.rapid_running.isTrue(); 196 | 197 | for(const auto& task : system_state_data_.rapid_tasks) 198 | { 199 | abb_robot_msgs::RAPIDTaskState state{}; 200 | 201 | state.name = task.name; 202 | state.activated = task.is_active; 203 | state.execution_state = utilities::map(task.execution_state); 204 | state.motion_task = task.is_motion_task; 205 | 206 | system_state_message.rapid_tasks.push_back(state); 207 | } 208 | 209 | for(const auto& unit : system_state_data_.mechanical_units) 210 | { 211 | abb_robot_msgs::MechanicalUnitState state{}; 212 | state.name = unit.first; 213 | state.activated = unit.second.active; 214 | system_state_message.mechanical_units.push_back(state); 215 | } 216 | 217 | //-------------------------------------------------------- 218 | // Parse StateMachine Add-In states 219 | //-------------------------------------------------------- 220 | abb_rapid_sm_addin_msgs::RuntimeState sm_runtime_state_message{}; 221 | const auto& system_indicators{robot_controller_description_.system_indicators()}; 222 | if(utilities::verifyStateMachineAddInPresence(system_indicators)) 223 | { 224 | for(const auto& sm : system_state_data_.state_machines) 225 | { 226 | abb_rapid_sm_addin_msgs::StateMachineState state{}; 227 | state.rapid_task = sm.rapid_task; 228 | state.sm_state = utilities::mapStateMachineState(sm.sm_state); 229 | state.egm_action = utilities::mapStateMachineEGMAction(sm.egm_action); 230 | sm_runtime_state_message.state_machines.push_back(state); 231 | } 232 | } 233 | 234 | //-------------------------------------------------------- 235 | // Publish the messages 236 | //-------------------------------------------------------- 237 | auto time_now{ros::Time::now()}; 238 | 239 | joint_state_message.header.stamp = time_now; 240 | joint_state_publisher_.publish(joint_state_message); 241 | 242 | system_state_message.header.stamp = time_now; 243 | system_state_publisher_.publish(system_state_message); 244 | 245 | sm_runtime_state_message.header.stamp = time_now; 246 | sm_runtime_state_publisher_.publish(sm_runtime_state_message); 247 | } 248 | 249 | } 250 | } 251 | --------------------------------------------------------------------------------