Skip to content

Commit 102204e

Browse files
committed
Remove chaining from controller and add trajectory_until node
This exposes an action to execute a trajectory, either until the trajectory is finished or until the "until" condition is met.
1 parent 395a09c commit 102204e

File tree

10 files changed

+581
-202
lines changed

10 files changed

+581
-202
lines changed

ur_controllers/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ find_package(generate_parameter_library REQUIRED)
2525
find_package(trajectory_msgs REQUIRED)
2626
find_package(control_msgs REQUIRED)
2727
find_package(action_msgs REQUIRED)
28+
find_package(rclcpp REQUIRED)
2829

2930

3031
set(THIS_PACKAGE_INCLUDE_DEPENDS
@@ -47,6 +48,7 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS
4748
control_msgs
4849
trajectory_msgs
4950
action_msgs
51+
rclcpp
5052
)
5153

5254
include_directories(include)
@@ -114,6 +116,15 @@ target_link_libraries(${PROJECT_NAME}
114116
passthrough_trajectory_controller_parameters
115117
ur_configuration_controller_parameters
116118
)
119+
120+
#
121+
# trajectory_until_node
122+
#
123+
add_executable(trajectory_until_node
124+
src/trajectory_until_node.cpp
125+
)
126+
ament_target_dependencies(trajectory_until_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${THIS_PACKAGE_INCLUDE_DEPENDS})
127+
117128
ament_target_dependencies(${PROJECT_NAME}
118129
${THIS_PACKAGE_INCLUDE_DEPENDS}
119130
)
@@ -124,6 +135,11 @@ target_compile_options(${PROJECT_NAME} PRIVATE -Wpedantic -Werror=return-type)
124135
target_compile_definitions(${PROJECT_NAME} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
125136
pluginlib_export_plugin_description_file(controller_interface controller_plugins.xml)
126137

138+
install(
139+
TARGETS trajectory_until_node
140+
DESTINATION lib/${PROJECT_NAME}
141+
)
142+
127143
install(TARGETS ${PROJECT_NAME}
128144
ARCHIVE DESTINATION lib
129145
LIBRARY DESTINATION lib

ur_controllers/controller_plugins.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
Controller used to get and change the configuration of the robot
3535
</description>
3636
</class>
37-
<class name="ur_controllers/ToolContactController" type="ur_controllers::ToolContactController" base_class_type="controller_interface::ChainableControllerInterface">
37+
<class name="ur_controllers/ToolContactController" type="ur_controllers::ToolContactController" base_class_type="controller_interface::ControllerInterface">
3838
<description>
3939
Chainable controller to use the tool contact functionality of the robot.
4040
</description>

ur_controllers/include/ur_controllers/tool_contact_controller.hpp

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#include <vector>
4646
#include <memory>
4747

48-
#include <controller_interface/chainable_controller_interface.hpp>
48+
#include <controller_interface/controller_interface.hpp>
4949
#include "std_msgs/msg/bool.hpp"
5050
#include <rclcpp_action/server.hpp>
5151
#include <rclcpp_action/create_server.hpp>
@@ -57,13 +57,16 @@
5757
#include <realtime_tools/realtime_server_goal_handle.hpp>
5858

5959
#include <ur_msgs/action/tool_contact.hpp>
60-
#include "tool_contact_controller_parameters.hpp"
60+
#include "ur_controllers/tool_contact_controller_parameters.hpp"
6161

6262
namespace ur_controllers
6363
{
64-
class ToolContactController : public controller_interface::ChainableControllerInterface
64+
class ToolContactController : public controller_interface::ControllerInterface
6565
{
6666
public:
67+
ToolContactController() = default;
68+
~ToolContactController() override = default;
69+
6770
controller_interface::CallbackReturn on_init() override;
6871

6972
controller_interface::InterfaceConfiguration command_interface_configuration() const override;
@@ -76,66 +79,9 @@ class ToolContactController : public controller_interface::ChainableControllerIn
7679

7780
controller_interface::CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override;
7881

79-
protected:
80-
/// Virtual method that each chainable controller should implement to export its read-only
81-
/// chainable interfaces.
82-
/**
83-
* Each chainable controller implements this methods where all its state(read only) interfaces are
84-
* exported. The method has the same meaning as `export_state_interfaces` method from
85-
* hardware_interface::SystemInterface or hardware_interface::ActuatorInterface.
86-
*
87-
* \returns list of StateInterfaces that other controller can use as their inputs.
88-
*/
89-
std::vector<hardware_interface::StateInterface> on_export_state_interfaces() override;
90-
91-
/// Virtual method that each chainable controller should implement to export its read/write
92-
/// chainable interfaces.
93-
/**
94-
* Each chainable controller implements this methods where all input (command) interfaces are
95-
* exported. The method has the same meaning as `export_command_interface` method from
96-
* hardware_interface::SystemInterface or hardware_interface::ActuatorInterface.
97-
*
98-
* \returns list of CommandInterfaces that other controller can use as their outputs.
99-
*/
100-
std::vector<hardware_interface::CommandInterface> on_export_reference_interfaces() override;
101-
102-
/// Virtual method that each chainable controller should implement to switch chained mode.
103-
/**
104-
* Each chainable controller implements this methods to switch between "chained" and "external"
105-
* mode. In "chained" mode all external interfaces like subscriber and service servers are
106-
* disabled to avoid potential concurrency in input commands.
107-
*
108-
* \param[in] flag marking a switch to or from chained mode.
109-
*
110-
* \returns true if controller successfully switched between "chained" and "external" mode.
111-
* \default returns true so the method don't have to be overridden if controller can always switch
112-
* chained mode.
113-
*/
114-
bool on_set_chained_mode(bool chained_mode) override;
115-
116-
/// Update reference from input topics when not in chained mode.
117-
/**
118-
* Each chainable controller implements this method to update reference from subscribers when not
119-
* in chained mode.
120-
*
121-
* \returns return_type::OK if update is successfully, otherwise return_type::ERROR.
122-
*/
123-
controller_interface::return_type update_reference_from_subscribers(const rclcpp::Time& time,
124-
const rclcpp::Duration& period) override;
125-
126-
/// Execute calculations of the controller and update command interfaces.
127-
/**
128-
* Update method for chainable controllers.
129-
* In this method is valid to assume that \reference_interfaces_ hold the values for calculation
130-
* of the commands in the current control step.
131-
* This means that this method is called after \update_reference_from_subscribers if controller is
132-
* not in chained mode.
133-
*
134-
* \returns return_type::OK if calculation and writing of interface is successfully, otherwise
135-
* return_type::ERROR.
136-
*/
137-
controller_interface::return_type update_and_write_commands(const rclcpp::Time& time,
138-
const rclcpp::Duration& period) override;
82+
controller_interface::CallbackReturn on_shutdown(const rclcpp_lifecycle::State& previous_state) override;
83+
84+
controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override;
13985

14086
private:
14187
using RealtimeGoalHandle = realtime_tools::RealtimeServerGoalHandle<ur_msgs::action::ToolContact>;
@@ -155,12 +101,14 @@ class ToolContactController : public controller_interface::ChainableControllerIn
155101
rclcpp_action::CancelResponse goal_cancelled_callback(
156102
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::ToolContact>> goal_handle);
157103

158-
void failed_update();
104+
controller_interface::return_type failed_update();
159105

160-
double tool_contact_enable;
161-
double tool_contact_active;
106+
double tool_contact_enable_ref_interface;
107+
double tool_contact_active_state_interface;
162108

109+
std::atomic<bool> tool_contact_enable_ = false;
163110
std::atomic<bool> tool_contact_active_ = false;
111+
std::atomic<bool> tool_contact_abort_ = false;
164112
std::atomic<bool> change_requested_ = false;
165113
std::atomic<bool> logged_once_ = false;
166114

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2025, Universal Robots A/S
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are met:
5+
//
6+
// * Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
//
9+
// * Redistributions in binary form must reproduce the above copyright
10+
// notice, this list of conditions and the following disclaimer in the
11+
// documentation and/or other materials provided with the distribution.
12+
//
13+
// * Neither the name of the {copyright_holder} nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
// POSSIBILITY OF SUCH DAMAGE.
28+
29+
//----------------------------------------------------------------------
30+
/*!\file
31+
*
32+
* \author Jacob Larsen [email protected]
33+
* \date 2025-01-17
34+
*
35+
*
36+
*
37+
*
38+
*/
39+
//----------------------------------------------------------------------
40+
41+
#ifndef UR_CONTROLLERS__TRAJECTORY_UNTIL_NODE_HPP_
42+
#define UR_CONTROLLERS__TRAJECTORY_UNTIL_NODE_HPP_
43+
44+
#include <memory>
45+
46+
#include "rclcpp/rclcpp.hpp"
47+
#include "std_msgs/msg/bool.hpp"
48+
#include <rclcpp_action/server.hpp>
49+
#include <rclcpp_action/rclcpp_action.hpp>
50+
#include <rclcpp_action/create_server.hpp>
51+
#include <rclcpp_action/server_goal_handle.hpp>
52+
#include <rclcpp/duration.hpp>
53+
#include <ur_msgs/action/tool_contact.hpp>
54+
#include <ur_msgs/action/trajectory_until.hpp>
55+
#include <control_msgs/action/follow_joint_trajectory.hpp>
56+
57+
namespace ur_controllers
58+
{
59+
60+
// template <typename action_type>
61+
class TrajectoryUntilNode : public rclcpp::Node
62+
{
63+
private:
64+
rclcpp_action::Server<ur_msgs::action::TrajectoryUntil>::SharedPtr action_server_;
65+
rclcpp_action::Client<control_msgs::action::FollowJointTrajectory>::SharedPtr trajectory_action_client_;
66+
rclcpp_action::Client<ur_msgs::action::ToolContact>::SharedPtr until_action_client_;
67+
68+
rclcpp::CallbackGroup::SharedPtr server_callback_group =
69+
create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
70+
rclcpp::CallbackGroup::SharedPtr clients_callback_group =
71+
create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
72+
73+
std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::TrajectoryUntil>> server_goal_handle_;
74+
75+
void
76+
until_response_callback(const rclcpp_action::ClientGoalHandle<ur_msgs::action::ToolContact>::SharedPtr& goal_handle);
77+
void
78+
until_result_callback(const rclcpp_action::ClientGoalHandle<ur_msgs::action::ToolContact>::WrappedResult& result);
79+
80+
void trajectory_response_callback(
81+
const rclcpp_action::ClientGoalHandle<control_msgs::action::FollowJointTrajectory>::SharedPtr& goal_handle);
82+
void trajectory_feedback_callback(
83+
const rclcpp_action::ClientGoalHandle<control_msgs::action::FollowJointTrajectory>::SharedPtr& goal_handle,
84+
const std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Feedback> feedback);
85+
void trajectory_result_callback(
86+
const rclcpp_action::ClientGoalHandle<control_msgs::action::FollowJointTrajectory>::WrappedResult& result);
87+
88+
void assign_until_action_client(std::shared_ptr<const ur_msgs::action::TrajectoryUntil::Goal> goal);
89+
90+
rclcpp_action::GoalResponse goal_received_callback(
91+
const rclcpp_action::GoalUUID& uuid, std::shared_ptr<const ur_msgs::action::TrajectoryUntil::Goal> goal);
92+
void goal_accepted_callback(
93+
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::TrajectoryUntil>> goal_handle);
94+
rclcpp_action::CancelResponse goal_cancelled_callback(
95+
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::TrajectoryUntil>> goal_handle);
96+
97+
void send_trajectory_goal(std::shared_ptr<const ur_msgs::action::TrajectoryUntil::Goal> goal);
98+
void send_until_goal(std::shared_ptr<const ur_msgs::action::TrajectoryUntil::Goal> goal);
99+
100+
void report_goal(auto result, bool until_triggered);
101+
102+
void reset_vars();
103+
104+
std::atomic<bool> trajectory_accepted_;
105+
std::atomic<bool> until_accepted_;
106+
107+
rclcpp_action::ClientGoalHandle<control_msgs::action::FollowJointTrajectory>::SharedPtr
108+
current_trajectory_goal_handle_;
109+
rclcpp_action::ClientGoalHandle<ur_msgs::action::ToolContact>::SharedPtr current_until_goal_handle_;
110+
111+
std::shared_ptr<ur_msgs::action::TrajectoryUntil::Result> prealloc_res =
112+
std::make_shared<ur_msgs::action::TrajectoryUntil::Result>(ur_msgs::action::TrajectoryUntil::Result());
113+
114+
std::shared_ptr<ur_msgs::action::TrajectoryUntil::Feedback> prealloc_fb =
115+
std::make_shared<ur_msgs::action::TrajectoryUntil::Feedback>(ur_msgs::action::TrajectoryUntil::Feedback());
116+
117+
std::condition_variable cv_until_;
118+
std::condition_variable cv_trajectory_;
119+
std::mutex mutex_until;
120+
std::mutex mutex_trajectory;
121+
122+
public:
123+
explicit TrajectoryUntilNode(const rclcpp::NodeOptions& options = rclcpp::NodeOptions());
124+
~TrajectoryUntilNode();
125+
};
126+
127+
} // namespace ur_controllers
128+
129+
#endif // UR_CONTROLLERS__TRAJECTORY_UNTIL_NODE_HPP_

ur_controllers/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<depend>control_msgs</depend>
4343
<depend>trajectory_msgs</depend>
4444
<depend>action_msgs</depend>
45+
<depend>rclcpp_components</depend>
4546

4647
<test_depend>controller_manager</test_depend>
4748
<test_depend>ros2_control_test_assets</test_depend>

0 commit comments

Comments
 (0)