cartesian_twist_controller.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. 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 OWNER 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 /*
31  * Author: Wim Meeussen
32  */
33 
35 #include <algorithm>
36 #include "kdl/chainfksolvervel_recursive.hpp"
38 
39 using namespace KDL;
40 
42 
43 namespace controller {
44 
45 
46 CartesianTwistController::CartesianTwistController()
47  : robot_state_(NULL),
48  jnt_to_twist_solver_(NULL)
49 {}
50 
51 
52 
54 {
56 }
57 
58 
60 {
61  node_ = n;
62 
63  // get name of root and tip from the parameter server
64  std::string root_name, tip_name;
65  if (!node_.getParam("root_name", root_name)){
66  ROS_ERROR("CartesianTwistController: No root name found on parameter server (namespace: %s)",
67  node_.getNamespace().c_str());
68  return false;
69  }
70  if (!node_.getParam("tip_name", tip_name)){
71  ROS_ERROR("CartesianTwistController: No tip name found on parameter server (namespace: %s)",
72  node_.getNamespace().c_str());
73  return false;
74  }
75 
76  // test if we got robot pointer
77  assert(robot_state);
78  robot_state_ = robot_state;
79 
80  // create robot chain from root to tip
81  if (!chain_.init(robot_state, root_name, tip_name))
82  return false;
83  if (!chain_.allCalibrated())
84  {
85  ROS_ERROR("Not all joints in the chain are calibrated (namespace: %s)", node_.getNamespace().c_str());
86  return false;
87  }
89 
90  // create solver
96 
97  // constructs 3 identical pid controllers: for the x,y and z translations
98  control_toolbox::Pid pid_controller;
99  if (!pid_controller.init(ros::NodeHandle(node_, "fb_trans"))) return false;
100  for (unsigned int i=0; i<3; i++)
101  fb_pid_controller_.push_back(pid_controller);
102 
103  // constructs 3 identical pid controllers: for the x,y and z rotations
104  if (!pid_controller.init(ros::NodeHandle(node_, "fb_rot"))) return false;
105  for (unsigned int i=0; i<3; i++)
106  fb_pid_controller_.push_back(pid_controller);
107 
108  // get parameters
109  node_.param("ff_trans", ff_trans_, 0.0) ;
110  node_.param("ff_rot", ff_rot_, 0.0) ;
111 
112  // subscribe to twist commands
113  sub_command_ = node_.subscribe<geometry_msgs::Twist>
114  ("command", 1, &CartesianTwistController::command, this);
115 
116  return true;
117 }
118 
120 {
121  // reset pid controllers
122  for (unsigned int i=0; i<6; i++)
123  fb_pid_controller_[i].reset();
124 
125  // time
127 
128  // set disired twist to 0
129  twist_desi_ = Twist::Zero();
130 }
131 
132 
133 
135 {
136  // check if joints are calibrated
137  if (!chain_.allCalibrated())
138  return;
139 
140  // get time
141  ros::Time time = robot_state_->getTime();
142  ros::Duration dt = time - last_time_;
143  last_time_ = time;
144 
145  // get the joint positions and velocities
147 
148  // get cartesian twist error
149  FrameVel twist;
150  jnt_to_twist_solver_->JntToCart(jnt_posvel_, twist);
151  twist_meas_ = twist.deriv();
153 
154  // get the chain jacobian
155  jac_solver_->JntToJac(jnt_posvel_.q, jacobian_);
156 
157  // pid feedback
158  for (unsigned int i=0; i<3; i++)
159  wrench_out_.force(i) = (twist_desi_.vel(i) * ff_trans_) + fb_pid_controller_[i].computeCommand(error.vel(i), dt);
160 
161  for (unsigned int i=0; i<3; i++)
162  wrench_out_.torque(i) = (twist_desi_.rot(i) * ff_rot_) + fb_pid_controller_[i+3].computeCommand(error.rot(i), dt);
163 
164  // Converts the wrench into joint efforts with a jacbobian-transpose
165  for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++){
166  jnt_eff_(i) = 0;
167  for (unsigned int j=0; j<6; j++)
168  jnt_eff_(i) += (jacobian_(j,i) * wrench_out_(j));
169  }
170 
171  // set effort to joints
173 }
174 
175 
176 void CartesianTwistController::command(const geometry_msgs::TwistConstPtr& twist_msg)
177 {
178  // convert to twist command
179  twist_desi_.vel(0) = twist_msg->linear.x;
180  twist_desi_.vel(1) = twist_msg->linear.y;
181  twist_desi_.vel(2) = twist_msg->linear.z;
182  twist_desi_.rot(0) = twist_msg->angular.x;
183  twist_desi_.rot(1) = twist_msg->angular.y;
184  twist_desi_.rot(2) = twist_msg->angular.z;
185 }
186 
187 } // namespace
PLUGINLIB_EXPORT_CLASS(my_controller_ns::MyControllerClass, pr2_controller_interface::Controller)
void resize(unsigned int newNrOfColumns)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
Vector vel
Vector torque
void getVelocities(std::vector< double > &)
double z() const
bool init(const ros::NodeHandle &n, const bool quiet=false)
Vector rot
double y() const
void resize(unsigned int newSize)
def error(args, kwargs)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
double x() const
const std::string & getNamespace() const
std::vector< control_toolbox::Pid > fb_pid_controller_
unsigned int getNrOfJoints() const
Vector force
bool init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n)
void resize(unsigned int newSize)
Twist deriv() const
bool getParam(const std::string &key, std::string &s) const
boost::scoped_ptr< KDL::ChainJntToJacSolver > jac_solver_
pr2_mechanism_model::RobotState * robot_state_
boost::scoped_ptr< KDL::ChainFkSolverVel > jnt_to_twist_solver_
bool init(RobotState *robot_state, const std::string &root, const std::string &tip)
void command(const geometry_msgs::TwistConstPtr &twist_msg)
#define ROS_ERROR(...)
void toKDL(KDL::Chain &chain)
void addEfforts(KDL::JntArray &)


robot_mechanism_controllers
Author(s): John Hsu, Melonee Wise, Stuart Glaser
autogenerated on Wed Jun 5 2019 19:34:03