Skip to content

Commit dd9b461

Browse files
committed
Update force torque state controller.
1 parent 8a07222 commit dd9b461

File tree

7 files changed

+158
-133
lines changed

7 files changed

+158
-133
lines changed

ur_controllers/CMakeLists.txt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ project(ur_controllers)
33

44
# Default to C++14
55
if(NOT CMAKE_CXX_STANDARD)
6-
set(CMAKE_CXX_STANDARD 14)
6+
set(CMAKE_CXX_STANDARD 14)
77
endif()
88

99
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
10-
add_compile_options(-Wall -Wextra)
10+
add_compile_options(-Wall -Wextra)
1111
endif()
1212

1313
find_package(ament_cmake REQUIRED)
@@ -20,13 +20,13 @@ find_package(rclcpp_lifecycle REQUIRED)
2020
find_package(rcutils REQUIRED)
2121

2222
set(THIS_PACKAGE_INCLUDE_DEPENDS
23-
controller_interface
24-
joint_trajectory_controller
25-
pluginlib
26-
std_msgs
27-
geometry_msgs
28-
rclcpp_lifecycle
29-
rcutils
23+
controller_interface
24+
joint_trajectory_controller
25+
pluginlib
26+
std_msgs
27+
geometry_msgs
28+
rclcpp_lifecycle
29+
rcutils
3030
)
3131

3232
include_directories(include)
@@ -35,9 +35,11 @@ add_library(${PROJECT_NAME} SHARED
3535
src/scaled_joint_trajectory_controller.cpp
3636
src/speed_scaling_state_controller.cpp
3737
src/force_torque_sensor_controller.cpp
38-
include/ur_controllers/force_torque_sensor_controller.h src/force_torque_sensor_controller.cpp)
38+
src/force_torque_sensor_controller.cpp)
3939

40-
target_include_directories(${PROJECT_NAME} PRIVATE include)
40+
target_include_directories(${PROJECT_NAME} PRIVATE
41+
include
42+
)
4143

4244
ament_target_dependencies(${PROJECT_NAME}
4345
${THIS_PACKAGE_INCLUDE_DEPENDS}
@@ -64,11 +66,11 @@ install(FILES controller_plugins.xml
6466
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
6567

6668
ament_export_include_directories(
67-
include
69+
include
6870
)
6971

7072
ament_export_libraries(
71-
${PROJECT_NAME}
73+
${PROJECT_NAME}
7274
)
7375

7476

ur_controllers/controller_plugins.xml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,3 @@
55
</description>
66
</class>
77
</library>
8-
<!--<library path="lib/libur_controllers">-->
9-
<!--<class name="ur_controllers/SpeedScalingStateController" type="ur_controllers::SpeedScalingStateController" base_class_type="controller_interface::ControllerBase">-->
10-
<!--<description>-->
11-
<!--This controller publishes the readings of all available speed scaling factors.-->
12-
<!--</description>-->
13-
<!--</class>-->
14-
<!--<class name="position_controllers/ScaledJointTrajectoryController" type="position_controllers::ScaledJointTrajectoryController" base_class_type="controller_interface::ControllerBase">-->
15-
<!--<description>-->
16-
<!--Scaled velocity-based joint trajectory controller-->
17-
<!--</description>-->
18-
<!--</class>-->
19-
<!--<class name="velocity_controllers/ScaledJointTrajectoryController" type="velocity_controllers::ScaledJointTrajectoryController" base_class_type="controller_interface::ControllerBase">-->
20-
<!--<description>-->
21-
<!--Scaled velocity-based joint trajectory controller-->
22-
<!--</description>-->
23-
<!--</class>-->
24-
<!--</library>-->

ur_controllers/include/ur_controllers/force_torque_sensor_controller.h

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
// Copyright (c) 2021 PickNik LLC
12
//
2-
// Created by livanov93 on 12/12/20.
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
36
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
414

515
#ifndef UR_CONTROLLERS_FORCE_TORQUE_SENSOR_CONTROLLER_H
616
#define UR_CONTROLLERS_FORCE_TORQUE_SENSOR_CONTROLLER_H
@@ -16,6 +26,38 @@
1626

1727
namespace ur_controllers
1828
{
29+
using FbkType = geometry_msgs::msg::WrenchStamped;
30+
31+
struct FTStateControllerParams
32+
{
33+
FTStateControllerParams()
34+
{
35+
sensor_name_ = "";
36+
state_interfaces_names_ = {};
37+
frame_id = "";
38+
topic_name = "";
39+
}
40+
41+
std::string sensor_name_;
42+
std::vector<std::string> state_interfaces_names_;
43+
std::string frame_id;
44+
std::string topic_name;
45+
};
46+
47+
/**
48+
* \brief Force torque state controller.
49+
*
50+
* This class forwards the command signal down to a set of joints
51+
* on the specified interface.
52+
*
53+
* \param topic_name Name of the topic to publish WrenchStamped msg
54+
* \param frame_id Frame of the ft sensor
55+
* \param sensor_name Names of the sensor which data should be published .
56+
* \param state_interface_names Names of the state interfaces in the sensor.
57+
*
58+
* Publishes to:
59+
* - \b topic_name (geometry_msg::msg::WrenchStamped) : Sensor data.
60+
*/
1961
class ForceTorqueStateController : public controller_interface::ControllerInterface
2062
{
2163
public:
@@ -36,12 +78,9 @@ class ForceTorqueStateController : public controller_interface::ControllerInterf
3678
controller_interface::return_type init(const std::string& controller_name) override;
3779

3880
protected:
39-
bool init_sensor_data();
40-
void init_sensor_state_msg();
41-
42-
// we store the name of values per axis - compatible interfaces
43-
std::vector<std::string> axis_val_names_;
44-
std::shared_ptr<rclcpp::Publisher<geometry_msgs::msg::WrenchStamped>> wrench_state_publisher_;
81+
// param storage
82+
FTStateControllerParams fts_params_;
83+
std::shared_ptr<rclcpp::Publisher<FbkType>> wrench_state_publisher_;
4584
geometry_msgs::msg::WrenchStamped wrench_state_msg_;
4685
};
4786
} // namespace ur_controllers

ur_controllers/src/force_torque_sensor_controller.cpp

Lines changed: 80 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
namespace ur_controllers
88
{
9-
ForceTorqueStateController::ForceTorqueStateController() : controller_interface::ControllerInterface()
9+
ForceTorqueStateController::ForceTorqueStateController()
10+
: controller_interface::ControllerInterface(), wrench_state_publisher_(nullptr)
1011
{
1112
}
1213

@@ -18,6 +19,20 @@ controller_interface::return_type ForceTorqueStateController::init(const std::st
1819
return ret;
1920
}
2021

22+
try
23+
{
24+
auto node = get_node();
25+
node->declare_parameter<std::vector<std::string>>("state_interface_names", {});
26+
node->declare_parameter<std::string>("sensor_name", "");
27+
node->declare_parameter<std::string>("topic_name", "");
28+
node->declare_parameter<std::string>("frame_id", "");
29+
}
30+
catch (const std::exception& e)
31+
{
32+
fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what());
33+
return controller_interface::return_type::ERROR;
34+
}
35+
2136
return controller_interface::return_type::SUCCESS;
2237
}
2338

@@ -32,13 +47,11 @@ controller_interface::InterfaceConfiguration ForceTorqueStateController::state_i
3247
{
3348
controller_interface::InterfaceConfiguration config;
3449
config.type = controller_interface::interface_configuration_type::INDIVIDUAL;
35-
// TODO solve this hardcoded naming
36-
config.names.emplace_back("tcp_fts_sensor/fx");
37-
config.names.emplace_back("tcp_fts_sensor/fy");
38-
config.names.emplace_back("tcp_fts_sensor/fz");
39-
config.names.emplace_back("tcp_fts_sensor/tx");
40-
config.names.emplace_back("tcp_fts_sensor/ty");
41-
config.names.emplace_back("tcp_fts_sensor/tz");
50+
for (const auto& si : fts_params_.state_interfaces_names_)
51+
{
52+
config.names.push_back(fts_params_.sensor_name_ + "/" + si);
53+
}
54+
4255
return config;
4356
}
4457

@@ -47,49 +60,38 @@ controller_interface::return_type ur_controllers::ForceTorqueStateController::up
4760
geometry_msgs::msg::Vector3 fVec;
4861
geometry_msgs::msg::Vector3 tVec;
4962

50-
// TODO remove these hardcoded names and create better string filtering within state_interfaces_
51-
for (const auto& state_interface : state_interfaces_)
52-
{
53-
if (state_interface.get_interface_name() == "fx")
54-
{
55-
fVec.set__x(state_interface.get_value());
56-
continue;
57-
}
58-
59-
if (state_interface.get_interface_name() == "fy")
60-
{
61-
fVec.set__y(state_interface.get_value());
62-
continue;
63-
}
63+
if (state_interfaces_.size() != fts_params_.state_interfaces_names_.size())
64+
return controller_interface::return_type::ERROR;
6465

65-
if (state_interface.get_interface_name() == "fz")
66-
{
67-
fVec.set__z(state_interface.get_value());
68-
continue;
69-
}
70-
71-
if (state_interface.get_interface_name() == "tx")
72-
{
73-
tVec.set__x(state_interface.get_value());
74-
continue;
75-
}
76-
77-
if (state_interface.get_interface_name() == "ty")
78-
{
79-
tVec.set__y(state_interface.get_value());
80-
continue;
81-
}
82-
83-
if (state_interface.get_interface_name() == "tz")
66+
for (auto index = 0ul; index < state_interfaces_.size(); ++index)
67+
{
68+
switch (index)
8469
{
85-
tVec.set__z(state_interface.get_value());
86-
continue;
70+
case 0:
71+
fVec.set__x(state_interfaces_[index].get_value());
72+
break;
73+
case 1:
74+
fVec.set__y(state_interfaces_[index].get_value());
75+
break;
76+
case 2:
77+
fVec.set__z(state_interfaces_[index].get_value());
78+
break;
79+
case 3:
80+
tVec.set__x(state_interfaces_[index].get_value());
81+
break;
82+
case 4:
83+
tVec.set__y(state_interfaces_[index].get_value());
84+
break;
85+
case 5:
86+
tVec.set__z(state_interfaces_[index].get_value());
87+
break;
88+
default:
89+
break;
8790
}
8891
}
8992

90-
// TODO set frame_id as parameter --> it includes tf listener within controller
9193
wrench_state_msg_.header.stamp = get_node()->get_clock()->now();
92-
wrench_state_msg_.header.frame_id = "tool0";
94+
wrench_state_msg_.header.frame_id = fts_params_.frame_id;
9395

9496
// update wrench state message
9597
wrench_state_msg_.wrench.set__force(fVec);
@@ -104,29 +106,52 @@ controller_interface::return_type ur_controllers::ForceTorqueStateController::up
104106
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
105107
ForceTorqueStateController::on_configure(const rclcpp_lifecycle::State& /*previous_state*/)
106108
{
109+
fts_params_.state_interfaces_names_ = node_->get_parameter("state_interface_names").as_string_array();
110+
111+
if (fts_params_.state_interfaces_names_.empty())
112+
{
113+
RCLCPP_ERROR(get_node()->get_logger(), "'state_interface_names' parameter was empty");
114+
return CallbackReturn::ERROR;
115+
}
116+
117+
fts_params_.sensor_name_ = node_->get_parameter("sensor_name").as_string();
118+
if (fts_params_.sensor_name_.empty())
119+
{
120+
RCLCPP_ERROR(get_node()->get_logger(), "'sensor_name' parameter was empty");
121+
return CallbackReturn::ERROR;
122+
}
123+
124+
fts_params_.topic_name = node_->get_parameter("topic_name").as_string();
125+
if (fts_params_.topic_name.empty())
126+
{
127+
RCLCPP_ERROR(get_node()->get_logger(), "'topic_name' parameter was empty");
128+
return CallbackReturn::ERROR;
129+
}
130+
131+
fts_params_.frame_id = node_->get_parameter("frame_id").as_string();
132+
if (fts_params_.frame_id.empty())
133+
{
134+
RCLCPP_ERROR(get_node()->get_logger(), "'frame_id' parameter was empty");
135+
return CallbackReturn::ERROR;
136+
}
137+
107138
try
108139
{
109-
// TODO make topic name a parameter
110-
wrench_state_publisher_ =
111-
get_node()->create_publisher<geometry_msgs::msg::WrenchStamped>("ft_data", rclcpp::SystemDefaultsQoS());
140+
// register ft sensor data publisher
141+
wrench_state_publisher_ = get_node()->create_publisher<geometry_msgs::msg::WrenchStamped>(
142+
fts_params_.topic_name, rclcpp::SystemDefaultsQoS());
112143
}
113144
catch (...)
114145
{
115146
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
116147
}
148+
117149
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
118150
}
119151

120152
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
121153
ForceTorqueStateController::on_activate(const rclcpp_lifecycle::State& /*previous_state*/)
122154
{
123-
if (!init_sensor_data())
124-
{
125-
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
126-
}
127-
128-
init_sensor_state_msg();
129-
130155
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
131156
}
132157

@@ -136,43 +161,6 @@ ForceTorqueStateController::on_deactivate(const rclcpp_lifecycle::State& /*previ
136161
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
137162
}
138163

139-
template <typename T>
140-
bool has_any_key(const std::unordered_map<std::string, T>& map, const std::vector<std::string>& keys)
141-
{
142-
bool found_key = false;
143-
for (const auto& key_item : map)
144-
{
145-
const auto& key = key_item.first;
146-
if (std::find(keys.cbegin(), keys.cend(), key) != keys.cend())
147-
{
148-
found_key = true;
149-
break;
150-
}
151-
}
152-
return found_key;
153-
}
154-
155-
bool ForceTorqueStateController::init_sensor_data()
156-
{
157-
bool has_fts_sensor = false;
158-
// loop in reverse order, this maintains the order of values at retrieval time
159-
for (auto si = state_interfaces_.crbegin(); si != state_interfaces_.crend(); si++)
160-
{
161-
// TODO remove hardcoded naming
162-
if (si->get_name() == "tcp_fts_sensor")
163-
{
164-
has_fts_sensor = true;
165-
axis_val_names_.push_back(si->get_interface_name());
166-
}
167-
}
168-
return has_fts_sensor;
169-
}
170-
171-
void ForceTorqueStateController::init_sensor_state_msg()
172-
{
173-
// default initialization for wrenchstamped state message
174-
}
175-
176164
} // namespace ur_controllers
177165

178166
#include "pluginlib/class_list_macros.hpp"

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ std::vector<hardware_interface::StateInterface> URPositionHardwareInterface::exp
133133
for (uint j = 0; j < info_.sensors[i].state_interfaces.size(); ++j)
134134
{
135135
state_interfaces.emplace_back(hardware_interface::StateInterface(
136-
info_.sensors[i].name, info_.sensors[i].state_interfaces[j].name, &urcl_ft_sensor_measurements_[i]));
136+
info_.sensors[i].name, info_.sensors[i].state_interfaces[j].name, &urcl_ft_sensor_measurements_[j]));
137137
}
138138
}
139139

0 commit comments

Comments
 (0)