Skip to content

Commit 1821c18

Browse files
committed
Initial version of the speed_scaling_state_controller
Controller is base on the current joint_state_controller of ros2 control
1 parent d40e9c2 commit 1821c18

File tree

7 files changed

+264
-12
lines changed

7 files changed

+264
-12
lines changed

ur_controllers/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,26 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
1111
endif()
1212

1313
find_package(ament_cmake REQUIRED)
14+
find_package(control_msgs REQUIRED)
1415
find_package(controller_interface REQUIRED)
1516
find_package(joint_trajectory_controller REQUIRED)
1617
find_package(pluginlib REQUIRED)
18+
find_package(rclcpp_lifecycle REQUIRED)
19+
find_package(realtime_tools REQUIRED)
20+
find_package(sensor_msgs REQUIRED)
1721
find_package(std_msgs REQUIRED)
1822
find_package(geometry_msgs REQUIRED)
1923
find_package(rclcpp_lifecycle REQUIRED)
2024
find_package(rcutils REQUIRED)
2125

2226
set(THIS_PACKAGE_INCLUDE_DEPENDS
27+
control_msgs
2328
controller_interface
2429
joint_trajectory_controller
2530
pluginlib
31+
rclcpp_lifecycle
32+
realtime_tools
33+
sensor_msgs
2634
std_msgs
2735
geometry_msgs
2836
rclcpp_lifecycle
@@ -64,6 +72,8 @@ install(FILES controller_plugins.xml
6472
)
6573

6674
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
75+
ament_export_include_directories(include)
76+
ament_export_libraries(${PROJECT_NAME})
6777

6878
ament_export_include_directories(
6979
include

ur_controllers/controller_plugins.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,19 @@
44
The force torque state controller publishes the current force and torques
55
</description>
66
</class>
7+
<class name="ur_controllers/SpeedScalingStateController" type="ur_controllers::SpeedScalingStateController" base_class_type="controller_interface::ControllerInterface">
8+
<description>
9+
This controller publishes the readings of all available speed scaling factors.
10+
</description>
11+
</class>
12+
<class name="position_controllers/ScaledJointTrajectoryController" type="position_controllers::ScaledJointTrajectoryController" base_class_type="controller_interface::ControllerBase">
13+
<description>
14+
Scaled velocity-based joint trajectory controller
15+
</description>
16+
</class>
17+
<class name="velocity_controllers/ScaledJointTrajectoryController" type="velocity_controllers::ScaledJointTrajectoryController" base_class_type="controller_interface::ControllerBase">
18+
<description>
19+
Scaled velocity-based joint trajectory controller
20+
</description>
21+
</class>
722
</library>

ur_controllers/include/ur_controllers/speed_scaling_state_controller.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,58 @@
1919
//----------------------------------------------------------------------
2020
/*!\file
2121
*
22-
* \author Felix Exner exner@fzi.de
23-
* \date 2019-04-17
22+
* \author Marvin Große Besselmann grosse@fzi.de
23+
* \date 2021-02-10
2424
*
2525
*/
2626
//----------------------------------------------------------------------
2727

2828
#ifndef UR_CONTROLLERS_SPEED_SCALING_STATE_CONTROLLER_H_INCLUDED
2929
#define UR_CONTROLLERS_SPEED_SCALING_STATE_CONTROLLER_H_INCLUDED
3030

31+
#include <memory>
32+
#include <string>
33+
#include <unordered_map>
34+
#include <vector>
35+
36+
#include "controller_interface/controller_interface.hpp"
37+
38+
#include "rclcpp_lifecycle/lifecycle_publisher.hpp"
39+
#include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp"
40+
#include "sensor_msgs/msg/joint_state.hpp"
41+
3142
namespace ur_controllers
3243
{
33-
class SpeedScalingStateController
44+
class SpeedScalingStateController : public controller_interface::ControllerInterface
3445
{
46+
public:
47+
SpeedScalingStateController();
48+
49+
controller_interface::InterfaceConfiguration command_interface_configuration() const override;
50+
51+
controller_interface::InterfaceConfiguration state_interface_configuration() const override;
52+
53+
controller_interface::return_type update() override;
54+
55+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
56+
on_configure(const rclcpp_lifecycle::State& previous_state) override;
57+
58+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
59+
on_activate(const rclcpp_lifecycle::State& previous_state) override;
60+
61+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
62+
on_deactivate(const rclcpp_lifecycle::State& previous_state) override;
63+
64+
protected:
65+
bool init_joint_data();
66+
void init_joint_state_msg();
67+
68+
protected:
69+
std::vector<std::string> joint_names_;
70+
std::shared_ptr<rclcpp::Publisher<sensor_msgs::msg::JointState>> joint_state_publisher_;
71+
sensor_msgs::msg::JointState joint_state_msg_;
72+
73+
std::unordered_map<std::string, std::unordered_map<std::string, double>> name_if_value_mapping_;
3574
};
3675
} // namespace ur_controllers
3776
#endif // ifndef UR_CONTROLLERS_SPEED_SCALING_STATE_CONTROLLER_H_INCLUDED

ur_controllers/package.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55
<version>0.0.0</version>
66
<description>Provides controllers that use the speed scaling interface of Universal Robots.</description>
77

8-
<maintainer email="exner@fzi.de">Felix Exner</maintainer>
8+
<maintainer email="grosse@fzi.de">Marvin Große Besselmann</maintainer>
99

1010
<license>Apache-2.0</license>
1111

1212
<buildtool_depend>ament_cmake</buildtool_depend>
1313

14-
<build_depend>pluginlib</build_depend>
15-
<build_depend>rcutils</build_depend>
16-
17-
<exec_depend>pluginlib</exec_depend>
18-
<exec_depend>rcutils</exec_depend>
1914

15+
<depend>control_msgs</depend>
2016
<depend>controller_interface</depend>
21-
<depend>rclcpp_lifecycle</depend>
2217
<depend>geometry_msgs</depend>
2318
<depend>joint_trajectory_controller</depend>
19+
<depend>pluginlib</depend>
20+
<depend>rclcpp_lifecycle</depend>
21+
<depend>rcutils</depend>
22+
<depend>realtime_tools</depend>
23+
<depend>sensor_msgs</depend>
2424
<depend>std_msgs</depend>
2525
<depend>std_srvs</depend>
2626
<depend>ur_client_library</depend>

ur_controllers/src/speed_scaling_state_controller.cpp

Lines changed: 184 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,192 @@
1919
//----------------------------------------------------------------------
2020
/*!\file
2121
*
22-
* \author Felix Exner exner@fzi.de
23-
* \date 2019-04-17
22+
* \author Marvin Große Besselmann grosse@fzi.de
23+
* \date 2021-02-10
2424
*
2525
*/
2626
//----------------------------------------------------------------------
2727

2828
#include "ur_controllers/speed_scaling_state_controller.h"
29+
30+
#include <stddef.h>
31+
#include <limits>
32+
#include <memory>
33+
#include <string>
34+
#include <unordered_map>
35+
#include <vector>
36+
37+
#include "hardware_interface/types/hardware_interface_return_values.hpp"
38+
#include "hardware_interface/types/hardware_interface_type_values.hpp"
39+
#include "rclcpp/clock.hpp"
40+
#include "rclcpp/qos.hpp"
41+
#include "rclcpp/qos_event.hpp"
42+
#include "rclcpp/time.hpp"
43+
#include "rclcpp_lifecycle/lifecycle_node.hpp"
44+
#include "rcpputils/split.hpp"
45+
#include "rcutils/logging_macros.h"
46+
#include "std_msgs/msg/header.hpp"
47+
48+
namespace rclcpp_lifecycle
49+
{
50+
class State;
51+
} // namespace rclcpp_lifecycle
52+
53+
namespace ur_controllers
54+
{
55+
const auto kUninitializedValue = std::numeric_limits<double>::quiet_NaN();
56+
using hardware_interface::HW_IF_POSITION;
57+
using hardware_interface::HW_IF_VELOCITY;
58+
using hardware_interface::HW_IF_EFFORT;
59+
60+
61+
SpeedScalingStateController::SpeedScalingStateController()
62+
{}
63+
64+
controller_interface::InterfaceConfiguration SpeedScalingStateController::command_interface_configuration()
65+
const
66+
{
67+
return controller_interface::InterfaceConfiguration{controller_interface::
68+
interface_configuration_type::NONE};
69+
}
70+
71+
controller_interface::InterfaceConfiguration SpeedScalingStateController::state_interface_configuration()
72+
const
73+
{
74+
return controller_interface::InterfaceConfiguration{controller_interface::
75+
interface_configuration_type::ALL};
76+
}
77+
78+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
79+
SpeedScalingStateController::on_configure(const rclcpp_lifecycle::State & /*previous_state*/)
80+
{
81+
try {
82+
// TODO change subscriber to single value
83+
joint_state_publisher_ = get_node()->create_publisher<sensor_msgs::msg::JointState>(
84+
"joint_states", rclcpp::SystemDefaultsQoS());
85+
86+
} catch (const std::exception & e) {
87+
// get_node() may throw, logging raw here
88+
fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what());
89+
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
90+
}
91+
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
92+
}
93+
94+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
95+
SpeedScalingStateController::on_activate(const rclcpp_lifecycle::State & /*previous_state*/)
96+
{
97+
if (!init_joint_data()) {
98+
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
99+
}
100+
101+
init_joint_state_msg();
102+
103+
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
104+
}
105+
106+
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
107+
SpeedScalingStateController::on_deactivate(const rclcpp_lifecycle::State & /*previous_state*/)
108+
{
109+
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
110+
}
111+
112+
template<typename T>
113+
bool has_any_key(
114+
const std::unordered_map<std::string, T> & map,
115+
const std::vector<std::string> & keys)
116+
{
117+
bool found_key = false;
118+
for (const auto & key_item : map) {
119+
const auto & key = key_item.first;
120+
if (std::find(keys.cbegin(), keys.cend(), key) != keys.cend()) {
121+
found_key = true;
122+
break;
123+
}
124+
}
125+
return found_key;
126+
}
127+
128+
bool SpeedScalingStateController::init_joint_data()
129+
{
130+
// loop in reverse order, this maintains the order of values at retrieval time
131+
for (auto si = state_interfaces_.crbegin(); si != state_interfaces_.crend(); si++) {
132+
// initialize map if name is new
133+
if (name_if_value_mapping_.count(si->get_name()) == 0) {
134+
name_if_value_mapping_[si->get_name()] = {};
135+
}
136+
// add interface name
137+
name_if_value_mapping_[si->get_name()][si->get_interface_name()] =
138+
kUninitializedValue;
139+
}
140+
141+
// filter state interfaces that have a speed scaling factor
142+
// the rest will be ignored for this message
143+
for (const auto & name_ifv : name_if_value_mapping_) {
144+
const auto & interfaces_and_values = name_ifv.second;
145+
if (has_any_key(interfaces_and_values, {"speed_scaling_factor"})) {
146+
joint_names_.push_back(name_ifv.first);
147+
}
148+
}
149+
150+
return true;
151+
}
152+
153+
void SpeedScalingStateController::init_joint_state_msg()
154+
{
155+
const size_t num_joints = joint_names_.size();
156+
157+
/// @note joint_state_msg publishes position, velocity and effort for all joints,
158+
/// with at least one of these interfaces, the rest are omitted from this message
159+
160+
// default initialization for joint state message
161+
joint_state_msg_.name = joint_names_;
162+
joint_state_msg_.position.resize(num_joints, kUninitializedValue);
163+
joint_state_msg_.velocity.resize(num_joints, kUninitializedValue);
164+
joint_state_msg_.effort.resize(num_joints, kUninitializedValue);
165+
}
166+
167+
double get_value(
168+
const std::unordered_map<std::string, std::unordered_map<std::string, double>> & map,
169+
const std::string & name, const std::string & interface_name)
170+
{
171+
const auto & interfaces_and_values = map.at(name);
172+
const auto interface_and_value = interfaces_and_values.find(interface_name);
173+
if (interface_and_value != interfaces_and_values.cend()) {
174+
return interface_and_value->second;
175+
} else {
176+
return kUninitializedValue;
177+
}
178+
}
179+
180+
controller_interface::return_type
181+
SpeedScalingStateController::update()
182+
{
183+
for (const auto & state_interface : state_interfaces_) {
184+
name_if_value_mapping_[state_interface.get_name()][state_interface.get_interface_name()] =
185+
state_interface.get_value();
186+
RCLCPP_DEBUG(
187+
get_node()->get_logger(), "%s/%s: %f\n",
188+
state_interface.get_name().c_str(),
189+
state_interface.get_interface_name().c_str(),
190+
state_interface.get_value());
191+
}
192+
193+
joint_state_msg_.header.stamp = node_->get_clock()->now();
194+
195+
for (auto i = 0ul; i < joint_names_.size(); ++i) {
196+
std::cout << get_value(name_if_value_mapping_, joint_names_[i], "speed_scaling_factor") << std::endl;
197+
}
198+
199+
// publish
200+
joint_state_publisher_->publish(joint_state_msg_);
201+
202+
return controller_interface::return_type::SUCCESS;
203+
}
204+
205+
} // namespace joint_state_controller
206+
207+
#include "pluginlib/class_list_macros.hpp"
208+
209+
PLUGINLIB_EXPORT_CLASS(
210+
ur_controllers::SpeedScalingStateController, controller_interface::ControllerInterface)

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ std::vector<hardware_interface::StateInterface> URPositionHardwareInterface::exp
127127
state_interfaces.emplace_back(hardware_interface::StateInterface(
128128
info_.joints[i].name, hardware_interface::HW_IF_EFFORT, &urcl_joint_efforts_[i]));
129129
}
130+
state_interfaces.emplace_back(hardware_interface::StateInterface(
131+
"speed", "speed_scaling_factor", &speed_scaling_
132+
));
130133

131134
for (auto& sensor : info_.sensors)
132135
{

ur_ros2_control_demos/config/ur_ros2_control.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ controller_manager:
88
joint_state_controller:
99
type: joint_state_controller/JointStateController
1010

11+
speed_scaling_state_controller:
12+
type: ur_controllers/SpeedScalingStateController
13+
1114
ur_joint_trajectory_controller:
1215
type: joint_trajectory_controller/JointTrajectoryController
1316

0 commit comments

Comments
 (0)