hardware_interface_adapter.h
Go to the documentation of this file.
1 // Copyright (C) 2013, PAL Robotics S.L.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of PAL Robotics S.L. nor the names of its
12 // contributors may be used to endorse or promote products derived from
13 // this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 // POSSIBILITY OF SUCH DAMAGE.
27 
29 
30 #pragma once
31 
32 
33 #include <cassert>
34 #include <string>
35 #include <vector>
36 #include <memory>
37 
38 #include <ros/node_handle.h>
39 #include <ros/time.h>
40 
41 #include <control_toolbox/pid.h>
45 
55 template <class HardwareInterface, class State>
57 {
58 public:
59  bool init(std::vector<typename HardwareInterface::ResourceHandleType>& /*joint_handles*/, ros::NodeHandle& /*controller_nh*/)
60  {
61  return false;
62  }
63 
64  void starting(const ros::Time& /*time*/) {}
65  void stopping(const ros::Time& /*time*/) {}
66 
67  void updateCommand(const ros::Time& /*time*/,
68  const ros::Duration& /*period*/,
69  const State& /*desired_state*/,
70  const State& /*state_error*/) {}
71 };
72 
93 template <class State>
94 class HardwareInterfaceAdapter<hardware_interface::PositionJointInterface, State>
95 {
96 public:
97  HardwareInterfaceAdapter() : joint_handles_ptr_(nullptr) {}
98 
99  bool init(std::vector<hardware_interface::JointHandle>& joint_handles, ros::NodeHandle& /*controller_nh*/)
100  {
101  // Store pointer to joint handles
102  joint_handles_ptr_ = &joint_handles;
103 
104  return true;
105  }
106 
107  void starting(const ros::Time& /*time*/)
108  {
109  if (!joint_handles_ptr_) {return;}
110 
111  // Semantic zero for commands
112  for (auto& jh : *joint_handles_ptr_)
113  {
114  jh.setCommand(jh.getPosition());
115  }
116  }
117 
118  void stopping(const ros::Time& /*time*/) {}
119 
120  void updateCommand(const ros::Time& /*time*/,
121  const ros::Duration& /*period*/,
122  const State& desired_state,
123  const State& /*state_error*/)
124  {
125  // Forward desired position to command
126  const unsigned int n_joints = joint_handles_ptr_->size();
127  for (unsigned int i = 0; i < n_joints; ++i) {(*joint_handles_ptr_)[i].setCommand(desired_state.position[i]);}
128  }
129 
130 private:
131  std::vector<hardware_interface::JointHandle>* joint_handles_ptr_;
132 };
133 
143 template <class State>
145 {
146 public:
147  ClosedLoopHardwareInterfaceAdapter() : joint_handles_ptr_(nullptr) {}
148 
149  bool init(std::vector<hardware_interface::JointHandle>& joint_handles, ros::NodeHandle& controller_nh)
150  {
151  // Store pointer to joint handles
152  joint_handles_ptr_ = &joint_handles;
153 
154  // Initialize PIDs
155  pids_.resize(joint_handles.size());
156  for (unsigned int i = 0; i < pids_.size(); ++i)
157  {
158  // Node handle to PID gains
159  ros::NodeHandle joint_nh(controller_nh, std::string("gains/") + joint_handles[i].getName());
160 
161  // Init PID gains from ROS parameter server
162  pids_[i].reset(new control_toolbox::Pid());
163  if (!pids_[i]->init(joint_nh))
164  {
165  ROS_WARN_STREAM("Failed to initialize PID gains from ROS parameter server.");
166  return false;
167  }
168  }
169 
170  // Load velocity feedforward gains from parameter server
171  velocity_ff_.resize(joint_handles.size());
172  for (unsigned int i = 0; i < velocity_ff_.size(); ++i)
173  {
174  controller_nh.param(std::string("velocity_ff/") + joint_handles[i].getName(), velocity_ff_[i], 0.0);
175  }
176 
177  return true;
178  }
179 
180  void starting(const ros::Time& /*time*/)
181  {
182  if (!joint_handles_ptr_) {return;}
183 
184  // Reset PIDs, zero commands
185  for (unsigned int i = 0; i < pids_.size(); ++i)
186  {
187  pids_[i]->reset();
188  (*joint_handles_ptr_)[i].setCommand(0.0);
189  }
190  }
191 
192  void stopping(const ros::Time& /*time*/) {}
193 
194  void updateCommand(const ros::Time& /*time*/,
195  const ros::Duration& period,
196  const State& desired_state,
197  const State& state_error)
198  {
199  const unsigned int n_joints = joint_handles_ptr_->size();
200 
201  // Preconditions
202  if (!joint_handles_ptr_)
203  return;
204  assert(n_joints == state_error.position.size());
205  assert(n_joints == state_error.velocity.size());
206 
207  // Update PIDs
208  for (unsigned int i = 0; i < n_joints; ++i)
209  {
210  const double command = (desired_state.velocity[i] * velocity_ff_[i]) + pids_[i]->computeCommand(state_error.position[i], state_error.velocity[i], period);
211  (*joint_handles_ptr_)[i].setCommand(command);
212  }
213  }
214 
215 private:
216  typedef std::shared_ptr<control_toolbox::Pid> PidPtr;
217  std::vector<PidPtr> pids_;
218 
219  std::vector<double> velocity_ff_;
220 
221  std::vector<hardware_interface::JointHandle>* joint_handles_ptr_;
222 };
223 
251 template <class State>
252 class HardwareInterfaceAdapter<hardware_interface::VelocityJointInterface, State> : public ClosedLoopHardwareInterfaceAdapter<State>
253 {};
254 
282 template <class State>
283 class HardwareInterfaceAdapter<hardware_interface::EffortJointInterface, State> : public ClosedLoopHardwareInterfaceAdapter<State>
284 {};
285 
289 template <class State>
290 class HardwareInterfaceAdapter<hardware_interface::PosVelJointInterface, State>
291 {
292 public:
293  HardwareInterfaceAdapter() : joint_handles_ptr_(nullptr) {}
294 
295  bool init(std::vector<hardware_interface::PosVelJointHandle>& joint_handles, ros::NodeHandle& /*controller_nh*/)
296  {
297  // Store pointer to joint handles
298  joint_handles_ptr_ = &joint_handles;
299 
300  return true;
301  }
302 
303  void starting(const ros::Time& /*time*/) {}
304  void stopping(const ros::Time& /*time*/) {}
305 
306  void updateCommand(const ros::Time& /*time*/,
307  const ros::Duration& /*period*/,
308  const State& desired_state,
309  const State& /*state_error*/)
310  {
311  // Forward desired position to command
312  const unsigned int n_joints = joint_handles_ptr_->size();
313  for (unsigned int i = 0; i < n_joints; ++i)
314  {
315  (*joint_handles_ptr_)[i].setCommand(desired_state.position[i], desired_state.velocity[i]);
316  }
317  }
318 
319 private:
320  std::vector<hardware_interface::PosVelJointHandle>* joint_handles_ptr_;
321 };
322 
326 template <class State>
327 class HardwareInterfaceAdapter<hardware_interface::PosVelAccJointInterface, State>
328 {
329 public:
330  HardwareInterfaceAdapter() : joint_handles_ptr_(nullptr) {}
331 
332  bool init(std::vector<hardware_interface::PosVelAccJointHandle>& joint_handles, ros::NodeHandle& /*controller_nh*/)
333  {
334  // Store pointer to joint handles
335  joint_handles_ptr_ = &joint_handles;
336 
337  return true;
338  }
339 
340  void starting(const ros::Time& /*time*/) {}
341  void stopping(const ros::Time& /*time*/) {}
342 
343  void updateCommand(const ros::Time& /*time*/,
344  const ros::Duration& /*period*/,
345  const State& desired_state,
346  const State& /*state_error*/)
347  {
348  // Forward desired position to command
349  const unsigned int n_joints = joint_handles_ptr_->size();
350  for (unsigned int i = 0; i < n_joints; ++i)
351  {
352  (*joint_handles_ptr_)[i].setCommand(desired_state.position[i], desired_state.velocity[i], desired_state.acceleration[i]);
353  }
354  }
355 
356 private:
357  std::vector<hardware_interface::PosVelAccJointHandle>* joint_handles_ptr_;
358 };
void updateCommand(const ros::Time &, const ros::Duration &, const State &desired_state, const State &)
bool init(std::vector< typename HardwareInterface::ResourceHandleType > &, ros::NodeHandle &)
std::vector< hardware_interface::PosVelAccJointHandle > * joint_handles_ptr_
void stopping(const ros::Time &)
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
bool init(std::vector< hardware_interface::JointHandle > &joint_handles, ros::NodeHandle &controller_nh)
bool init(std::vector< hardware_interface::JointHandle > &joint_handles, ros::NodeHandle &)
std::vector< hardware_interface::JointHandle > * joint_handles_ptr_
std::vector< hardware_interface::PosVelJointHandle > * joint_handles_ptr_
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void updateCommand(const ros::Time &, const ros::Duration &period, const State &desired_state, const State &state_error)
ROSLIB_DECL std::string command(const std::string &cmd)
Helper base class template for closed loop HardwareInterfaceAdapter implementations.
void updateCommand(const ros::Time &, const ros::Duration &, const State &, const State &)
void updateCommand(const ros::Time &, const ros::Duration &, const State &desired_state, const State &)
#define ROS_WARN_STREAM(args)
Helper class to simplify integrating the JointTrajectoryController with different hardware interfaces...
std::shared_ptr< control_toolbox::Pid > PidPtr
void starting(const ros::Time &)
bool init(std::vector< hardware_interface::PosVelAccJointHandle > &joint_handles, ros::NodeHandle &)
bool init(std::vector< hardware_interface::PosVelJointHandle > &joint_handles, ros::NodeHandle &)
void updateCommand(const ros::Time &, const ros::Duration &, const State &desired_state, const State &)


joint_trajectory_controller
Author(s): Adolfo Rodriguez Tsouroukdissian
autogenerated on Fri Feb 3 2023 03:19:15