|
| 1 | +// Copyright 2024, 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 2024-03-11 |
| 34 | + * |
| 35 | + * |
| 36 | + * |
| 37 | + * |
| 38 | + */ |
| 39 | +//---------------------------------------------------------------------- |
| 40 | + |
| 41 | +#ifndef UR_CONTROLLERS__PASSTHROUGH_TRAJECTORY_CONTROLLER_HPP_ |
| 42 | +#define UR_CONTROLLERS__PASSTHROUGH_TRAJECTORY_CONTROLLER_HPP_ |
| 43 | + |
| 44 | +#include <stdint.h> |
| 45 | + |
| 46 | +#include <realtime_tools/realtime_buffer.h> |
| 47 | +#include <realtime_tools/realtime_server_goal_handle.h> |
| 48 | + |
| 49 | +#include <functional> |
| 50 | +#include <limits> |
| 51 | +#include <memory> |
| 52 | +#include <string> |
| 53 | +#include <unordered_map> |
| 54 | +#include <vector> |
| 55 | + |
| 56 | +#include <controller_interface/controller_interface.hpp> |
| 57 | +#include <rclcpp_action/server.hpp> |
| 58 | +#include <rclcpp_action/create_server.hpp> |
| 59 | +#include <rclcpp/rclcpp.hpp> |
| 60 | +#include <rclcpp_action/server_goal_handle.hpp> |
| 61 | +#include <rclcpp/time.hpp> |
| 62 | +#include <rclcpp/duration.hpp> |
| 63 | +#include <rclcpp/clock.hpp> |
| 64 | + |
| 65 | +#include <trajectory_msgs/msg/joint_trajectory.hpp> |
| 66 | +#include <control_msgs/action/follow_joint_trajectory.hpp> |
| 67 | + |
| 68 | +#include "passthrough_trajectory_controller_parameters.hpp" |
| 69 | + |
| 70 | +namespace ur_controllers |
| 71 | +{ |
| 72 | + |
| 73 | +/* |
| 74 | + * 0.0: No trajectory to forward, the controller is idling and ready to receive a new trajectory. |
| 75 | + * 1.0: The controller has received and accepted a new trajectory. When the state is 1.0, the controller will write a |
| 76 | + * point to the hardware interface. |
| 77 | + * 2.0: The hardware interface will read the point written from the controller. The state will switch between 1.0 |
| 78 | + * and 2.0 until all points have been read by the hardware interface. |
| 79 | + * 3.0: The hardware interface has read all the points, and will now write all the points to the physical robot |
| 80 | + * controller. |
| 81 | + * 4.0: The robot is moving through the trajectory. |
| 82 | + * 5.0: The robot finished executing the trajectory. |
| 83 | + */ |
| 84 | +const double TRANSFER_STATE_IDLE = 0.0; |
| 85 | +const double TRANSFER_STATE_WAITING_FOR_POINT = 1.0; |
| 86 | +const double TRANSFER_STATE_TRANSFERRING = 2.0; |
| 87 | +const double TRANSFER_STATE_TRANSFER_DONE = 3.0; |
| 88 | +const double TRANSFER_STATE_IN_MOTION = 4.0; |
| 89 | +const double TRANSFER_STATE_DONE = 5.0; |
| 90 | + |
| 91 | +using namespace std::chrono_literals; // NOLINT |
| 92 | + |
| 93 | +class PassthroughTrajectoryController : public controller_interface::ControllerInterface |
| 94 | +{ |
| 95 | +public: |
| 96 | + PassthroughTrajectoryController() = default; |
| 97 | + ~PassthroughTrajectoryController() override = default; |
| 98 | + |
| 99 | + controller_interface::InterfaceConfiguration state_interface_configuration() const override; |
| 100 | + |
| 101 | + controller_interface::InterfaceConfiguration command_interface_configuration() const override; |
| 102 | + |
| 103 | + controller_interface::CallbackReturn on_init() override; |
| 104 | + |
| 105 | + controller_interface::CallbackReturn on_configure(const rclcpp_lifecycle::State& previous_state) override; |
| 106 | + |
| 107 | + controller_interface::CallbackReturn on_activate(const rclcpp_lifecycle::State& state) override; |
| 108 | + |
| 109 | + controller_interface::CallbackReturn on_deactivate(const rclcpp_lifecycle::State& state) override; |
| 110 | + |
| 111 | + controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override; |
| 112 | + |
| 113 | +private: |
| 114 | + using FollowJTrajAction = control_msgs::action::FollowJointTrajectory; |
| 115 | + using RealtimeGoalHandle = realtime_tools::RealtimeServerGoalHandle<FollowJTrajAction>; |
| 116 | + using RealtimeGoalHandlePtr = std::shared_ptr<RealtimeGoalHandle>; |
| 117 | + using RealtimeGoalHandleBuffer = realtime_tools::RealtimeBuffer<RealtimeGoalHandlePtr>; |
| 118 | + |
| 119 | + RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. |
| 120 | + rclcpp::TimerBase::SharedPtr goal_handle_timer_; ///< Timer to frequently check on the running goal |
| 121 | + realtime_tools::RealtimeBuffer<std::unordered_map<std::string, size_t>> joint_trajectory_mapping_; |
| 122 | + |
| 123 | + rclcpp::Duration action_monitor_period_ = rclcpp::Duration(50ms); |
| 124 | + |
| 125 | + /* Start an action server with an action called: /passthrough_trajectory_controller/forward_joint_trajectory. */ |
| 126 | + void start_action_server(void); |
| 127 | + |
| 128 | + void end_goal(); |
| 129 | + |
| 130 | + bool check_goal_tolerance(); |
| 131 | + |
| 132 | + // Get a mapping between the trajectory's joint order and the internal one |
| 133 | + std::unordered_map<std::string, size_t> create_joint_mapping(const std::vector<std::string>& joint_names) const; |
| 134 | + |
| 135 | + std::shared_ptr<passthrough_trajectory_controller::ParamListener> passthrough_param_listener_; |
| 136 | + passthrough_trajectory_controller::Params passthrough_params_; |
| 137 | + |
| 138 | + rclcpp_action::Server<control_msgs::action::FollowJointTrajectory>::SharedPtr send_trajectory_action_server_; |
| 139 | + |
| 140 | + rclcpp_action::GoalResponse |
| 141 | + goal_received_callback(const rclcpp_action::GoalUUID& uuid, |
| 142 | + std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal); |
| 143 | + |
| 144 | + rclcpp_action::CancelResponse goal_cancelled_callback( |
| 145 | + const std::shared_ptr<rclcpp_action::ServerGoalHandle<control_msgs::action::FollowJointTrajectory>> goal_handle); |
| 146 | + |
| 147 | + void goal_accepted_callback( |
| 148 | + std::shared_ptr<rclcpp_action::ServerGoalHandle<control_msgs::action::FollowJointTrajectory>> goal_handle); |
| 149 | + |
| 150 | + realtime_tools::RealtimeBuffer<std::vector<std::string>> joint_names_; |
| 151 | + std::vector<std::string> state_interface_types_; |
| 152 | + |
| 153 | + std::vector<std::string> joint_state_interface_names_; |
| 154 | + std::vector<std::reference_wrapper<hardware_interface::LoanedStateInterface>> joint_position_state_interface_; |
| 155 | + std::vector<std::reference_wrapper<hardware_interface::LoanedStateInterface>> joint_velocity_state_interface_; |
| 156 | + std::vector<std::reference_wrapper<hardware_interface::LoanedStateInterface>> joint_acceleration_state_interface_; |
| 157 | + |
| 158 | + bool check_goal_tolerances(std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal); |
| 159 | + bool check_goal_positions(std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal); |
| 160 | + bool check_goal_velocities(std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal); |
| 161 | + bool check_goal_accelerations(std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal); |
| 162 | + |
| 163 | + trajectory_msgs::msg::JointTrajectory active_joint_traj_; |
| 164 | + // std::vector<control_msgs::msg::JointTolerance> path_tolerance_; |
| 165 | + realtime_tools::RealtimeBuffer<std::vector<control_msgs::msg::JointTolerance>> goal_tolerance_; |
| 166 | + realtime_tools::RealtimeBuffer<rclcpp::Duration> goal_time_tolerance_{ rclcpp::Duration(0, 0) }; |
| 167 | + |
| 168 | + std::atomic<size_t> current_index_; |
| 169 | + std::atomic<bool> trajectory_active_; |
| 170 | + rclcpp::Duration active_trajectory_elapsed_time_ = rclcpp::Duration::from_nanoseconds(0); |
| 171 | + rclcpp::Duration max_trajectory_time_ = rclcpp::Duration::from_nanoseconds(0); |
| 172 | + double scaling_factor_; |
| 173 | + std::atomic<size_t> number_of_joints_; |
| 174 | + static constexpr double NO_VAL = std::numeric_limits<double>::quiet_NaN(); |
| 175 | + |
| 176 | + std::optional<std::reference_wrapper<hardware_interface::LoanedStateInterface>> scaling_state_interface_; |
| 177 | + std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> abort_command_interface_; |
| 178 | + std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> transfer_command_interface_; |
| 179 | + std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> time_from_start_command_interface_; |
| 180 | + |
| 181 | + rclcpp::Clock::SharedPtr clock_; |
| 182 | +}; |
| 183 | +} // namespace ur_controllers |
| 184 | +#endif // UR_CONTROLLERS__PASSTHROUGH_TRAJECTORY_CONTROLLER_HPP_ |
0 commit comments