ros2_control - humble
Loading...
Searching...
No Matches
hardware_interface_adapter.hpp
1// Copyright 2014, SRI International
2// Copyright 2013, PAL Robotics S.L.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
17
18#ifndef GRIPPER_CONTROLLERS__HARDWARE_INTERFACE_ADAPTER_HPP_
19#define GRIPPER_CONTROLLERS__HARDWARE_INTERFACE_ADAPTER_HPP_
20
21#include <algorithm>
22#include <cassert>
23#include <memory>
24#include <string>
25#include <vector>
26
27#include "control_toolbox/pid.hpp"
28#include "hardware_interface/types/hardware_interface_type_values.hpp"
29#include "rclcpp/time.hpp"
30#include "rclcpp_lifecycle/lifecycle_node.hpp"
31
40template <const char * HardwareInterface>
42{
43public:
44 bool init(
45 std::optional<
46 std::reference_wrapper<hardware_interface::LoanedCommandInterface>> /* joint_handle */,
47 std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & /* node */)
48 {
49 return false;
50 }
51
52 void starting(const rclcpp::Time & /* time */) {}
53 void stopping(const rclcpp::Time & /* time */) {}
54
55 double updateCommand(
56 double /* desired_position */, double /* desired_velocity */, double /* error_position */,
57 double /* error_velocity */, double /* max_allowed_effort */)
58 {
59 return 0.0;
60 }
61};
62
67template <>
69{
70public:
71 bool init(
72 std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> joint_handle,
73 const rclcpp_lifecycle::LifecycleNode::SharedPtr & /* node */)
74 {
75 joint_handle_ = joint_handle;
76 return true;
77 }
78
79 void starting(const rclcpp::Time & /* time */) {}
80 void stopping(const rclcpp::Time & /* time */) {}
81
82 double updateCommand(
83 double desired_position, double /* desired_velocity */, double /* error_position */,
84 double /* error_velocity */, double max_allowed_effort)
85 {
86 // Forward desired position to command
87 joint_handle_->get().set_value(desired_position);
88 return max_allowed_effort;
89 }
90
91private:
92 std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> joint_handle_;
93};
94
109template <>
111{
112public:
113 template <typename ParameterT>
114 auto auto_declare(
115 const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node, const std::string & name,
116 const ParameterT & default_value)
117 {
118 if (!node->has_parameter(name))
119 {
120 return node->declare_parameter<ParameterT>(name, default_value);
121 }
122 else
123 {
124 return node->get_parameter(name).get_value<ParameterT>();
125 }
126 }
127
128 bool init(
129 std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> joint_handle,
130 const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node)
131 {
132 joint_handle_ = joint_handle;
133 // Init PID gains from ROS parameter server
134 const std::string prefix = "gains." + joint_handle_->get().get_prefix_name();
135 const auto k_p = auto_declare<double>(node, prefix + ".p", 0.0);
136 const auto k_i = auto_declare<double>(node, prefix + ".i", 0.0);
137 const auto k_d = auto_declare<double>(node, prefix + ".d", 0.0);
138 const auto i_clamp = auto_declare<double>(node, prefix + ".i_clamp", 0.0);
139 // Initialize PID
140 pid_ = std::make_shared<control_toolbox::Pid>(k_p, k_i, k_d, i_clamp, -i_clamp);
141 return true;
142 }
143
144 void starting(const rclcpp::Time & /* time */)
145 {
146 if (!joint_handle_)
147 {
148 return;
149 }
150 // Reset PIDs, zero effort commands
151 pid_->reset();
152 joint_handle_->get().set_value(0.0);
153 }
154
155 void stopping(const rclcpp::Time & /* time */) {}
156
157 double updateCommand(
158 double /* desired_position */, double /* desired_velocity */, double error_position,
159 double error_velocity, double max_allowed_effort)
160 {
161 // Preconditions
162 if (!joint_handle_)
163 {
164 return 0.0;
165 }
166 // Time since the last call to update
167 const auto period = std::chrono::steady_clock::now() - last_update_time_;
168 // Update PIDs
169 double command =
170 pid_->computeCommand(error_position, error_velocity, static_cast<uint64_t>(period.count()));
171 command = std::min<double>(
172 fabs(max_allowed_effort), std::max<double>(-fabs(max_allowed_effort), command));
173 joint_handle_->get().set_value(command);
174 last_update_time_ = std::chrono::steady_clock::now();
175 return command;
176 }
177
178private:
179 using PidPtr = std::shared_ptr<control_toolbox::Pid>;
180 PidPtr pid_;
181 std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> joint_handle_;
182 std::chrono::steady_clock::time_point last_update_time_;
183};
184
185#endif // GRIPPER_CONTROLLERS__HARDWARE_INTERFACE_ADAPTER_HPP_
Helper class to simplify integrating the GripperActionController with different hardware interfaces.
Definition hardware_interface_adapter.hpp:42
Definition actuator.hpp:31