xarm_hw.cpp
Go to the documentation of this file.
1 /* Copyright 2018 UFACTORY Inc. All Rights Reserved.
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Author: Jason Peng <jason@ufactory.cc>
6  ============================================================================*/
7 
8 #include "xarm_hw.h"
9 
10 namespace xarm_control
11 {
12  void XArmHW::_register_joint_limits(ros::NodeHandle &root_nh, std::string joint_name, const ControlMethod ctrl_method)
13  {
16  bool has_limits = false;
17  bool has_soft_limits = false;
18 
19  urdf::JointConstSharedPtr urdf_joint = model_ptr_->getJoint(joint_name);
20  if (urdf_joint != NULL)
21  {
22  // Get limits from the URDF file.
23  if (joint_limits_interface::getJointLimits(urdf_joint, joint_limits))
24  has_limits = true;
25  if (joint_limits_interface::getSoftJointLimits(urdf_joint, soft_joint_limits))
26  has_soft_limits = true;
27  }
28  // Get limits from the parameter server.
29  if (joint_limits_interface::getJointLimits(joint_name, root_nh, joint_limits))
30  has_limits = true;
31 
32  if (!has_limits)
33  return;
34 
35  switch (ctrl_method)
36  {
37  case EFFORT:
38  {
39  if (has_soft_limits)
40  ej_limits_interface_.registerHandle(joint_limits_interface::EffortJointSoftLimitsHandle(ej_interface_.getHandle(joint_name), joint_limits, soft_joint_limits));
41  else
43  }
44  break;
45  case VELOCITY:
46  {
47  if (has_soft_limits)
48  vj_limits_interface_.registerHandle(joint_limits_interface::VelocityJointSoftLimitsHandle(vj_interface_.getHandle(joint_name), joint_limits, soft_joint_limits));
49  else
51  }
52  break;
53  case POSITION:
54  default:
55  {
56  if (has_soft_limits)
57  pj_limits_interface_.registerHandle(joint_limits_interface::PositionJointSoftLimitsHandle(pj_interface_.getHandle(joint_name), joint_limits, soft_joint_limits));
58  else
60  }
61  break;
62  }
63  printf("%s, ctrl_method=%d, has_soft_limits=%d, has_velocity_limits=%d, max_velocity=%f, has_position_limits=%d, min_position=%f, max_position=%f\n",
64  joint_name.c_str(), ctrl_method, has_soft_limits, joint_limits.has_velocity_limits, joint_limits.max_velocity,
65  joint_limits.has_position_limits, joint_limits.min_position, joint_limits.max_position);
66  }
67 
68  void XArmHW::clientInit(const std::string& robot_ip, ros::NodeHandle& root_nh)
69  {
70  position_cmd_.resize(dof_);
71  position_cmd_float_.resize(dof_); // command vector must have 7 dimention!
72  position_fdb_.resize(dof_);
73  velocity_cmd_.resize(dof_);
74  velocity_cmd_float_.resize(dof_);
75  velocity_fdb_.resize(dof_);
76  effort_cmd_.resize(dof_);
77  effort_fdb_.resize(dof_);
78 
79  curr_err = 0;
80  curr_state = 0;
81 
82  pos_sub_ = root_nh.subscribe(jnt_state_topic, 100, &XArmHW::pos_fb_cb, this);
84 
85  for(unsigned int j=0; j < dof_; j++)
86  {
87  // Create joint state interface for all joints
89  switch (ctrl_method_)
90  {
91  case EFFORT:
92  {
94  }
95  break;
96  case VELOCITY:
97  {
99  }
100  break;
101  case POSITION:
102  default:
103  {
106  }
107  break;
108  }
110  }
111 
113  switch (ctrl_method_)
114  {
115  case EFFORT:
117  break;
118  case VELOCITY:
120  break;
121  case POSITION:
122  default:
124  break;
125  }
126 
127  int ret1 = xarm.motionEnable(1);
129  int ret3 = xarm.setState(XARM_STATE::START);
130 
131  if(ret3)
132  {
133  ROS_ERROR("The Xarm may not be properly connected (ret = 3) or hardware Error/Warning (ret = 1 or 2) exists, PLEASE CHECK or RESTART HARDWARE!!!");
134  ROS_ERROR(" ");
135  ROS_ERROR("Did you specify the correct ros param xarm_robot_ip ? Exitting...");
136  ros::shutdown();
137  exit(1);
138  }
139 
140  }
141 
142  bool XArmHW::init(ros::NodeHandle& root_nh, ros::NodeHandle& robot_hw_nh)
143  {
144  // ctrl_method_ = EFFORT; // INVALID
145  // ctrl_method_ = VELOCITY; // INVALID
146  ctrl_method_ = POSITION; // RELEASE
147 
148  hw_ns_ = robot_hw_nh.getNamespace() + "/";
149  ros::service::waitForService(hw_ns_+"motion_ctrl");
152  if (ctrl_method_ == VELOCITY)
153  ros::service::waitForService(hw_ns_+"velo_move_joint");
154  else
155  ros::service::waitForService(hw_ns_+"move_servoj");
156  xarm.init(robot_hw_nh);
157  std::string robot_ip;
158  std::vector<std::string> jnt_names;
159  int xarm_dof = 0;
160 
161  if(!robot_hw_nh.hasParam("DOF"))
162  {
163  ROS_ERROR("ROS Parameter xarm_dof not specified!");
164  return false;
165  }
166  if(!robot_hw_nh.hasParam("xarm_robot_ip"))
167  {
168  ROS_ERROR("ROS Parameter xarm_robot_ip not specified!");
169  return false;
170  }
171  // If there is no /robot_description parameter, moveit controller may send zero command even controller fails to initialize
172  if(!robot_hw_nh.hasParam("/robot_description"))
173  {
174  ROS_ERROR("ROS Parameter /robot_description not specified!");
175  return false;
176  }
177 
178  /* getParam forbids to change member */
179  robot_hw_nh.getParam("DOF", xarm_dof);
180  robot_hw_nh.getParam("xarm_robot_ip", robot_ip);
181  robot_hw_nh.getParam("joint_names", jnt_names);
182 
183  dof_ = xarm_dof;
184  jnt_names_ = jnt_names;
185  initial_write_ = true;
186 
187  std::string robot_description;
188  root_nh.getParam("/robot_description", robot_description);
189  model_ptr_ = urdf::parseURDF(robot_description);
190 
191  clientInit(robot_ip, robot_hw_nh);
192  return true;
193  }
194 
196  {
198  }
199 
200  void XArmHW::pos_fb_cb(const sensor_msgs::JointState::ConstPtr& data)
201  {
202  std::lock_guard<std::mutex> locker(mutex_);
203  for(int j=0; j<dof_; j++)
204  {
205  position_fdb_[j] = data->position[j];
206  velocity_fdb_[j] = data->velocity[j];
207  effort_fdb_[j] = data->effort[j];
208  }
209  }
210 
211  void XArmHW::state_fb_cb(const xarm_msgs::RobotMsg::ConstPtr& data)
212  {
213  curr_mode = data->mode;
214  curr_state = data->state;
215  curr_err = data->err;
216  }
217 
219  {
222  }
223 
225  {
226  switch (ctrl_method_)
227  {
228  case EFFORT:
229  {
232  }
233  break;
234  case VELOCITY:
235  {
238  }
239  break;
240  case POSITION:
241  default:
242  {
245  }
246  break;
247  }
248  }
249 
250  void XArmHW::read(const ros::Time& time, const ros::Duration& period)
251  {
252  // basically the above feedback callback functions have done the job
253  }
254 
255  void XArmHW::write(const ros::Time& time, const ros::Duration& period)
256  {
257 
258  if(initial_write_ || need_reset())
259  {
260  std::lock_guard<std::mutex> locker(mutex_);
261  for(int k=0; k<dof_; k++)
262  {
263  position_cmd_float_[k] = (float)position_fdb_[k];
264  velocity_cmd_float_[k] = 0;
265  }
266  _reset_limits();
267  initial_write_ = false;
268  return;
269  }
270 
271  _enforce_limits(period);
272 
273  int cmd_ret = 0;
274  switch (ctrl_method_)
275  {
276  case VELOCITY:
277  {
278  for (int k = 0; k < dof_; k++) { velocity_cmd_float_[k] = (float)velocity_cmd_[k]; }
279  cmd_ret = xarm.veloMoveJoint(velocity_cmd_float_, true);
280  }
281  break;
282  case POSITION:
283  default:
284  {
285  for (int k = 0; k < dof_; k++) { position_cmd_float_[k] = (float)position_cmd_[k]; }
287  }
288  break;
289  }
290 
291  if(cmd_ret)
292  {
294  ROS_ERROR("XArmHW::Write() Error! Code: %d, Setting Robot State to STOP...", cmd_ret);
295  }
296 
297  // for(int k=0; k<dof_; k++)
298  // {
299  // // make sure no abnormal command will be written into joints, check if cmd velocity > [180 deg/sec * (1+10%)]
300  // if(fabs(position_cmd_float_[k]-(float)position_cmd_[k])/(period.toSec()) > 3.14*1.25 && !initial_write_)
301  // {
302  // ROS_WARN("joint %d abnormal command! previous: %f, this: %f\n", k+1, position_cmd_float_[k], (float)position_cmd_[k]);
303  // // return;
304  // }
305 
306  // position_cmd_float_[k] = (float)position_cmd_[k];
307  // }
308 
309  // xarm.setServoJ(position_cmd_float_);
310 
311  // initial_write_ = false;
312  }
313 
314  void XArmHW::get_status(int state_mode_err[3])
315  {
316  state_mode_err[0] = curr_state;
317  state_mode_err[1] = curr_mode;
318  state_mode_err[2] = curr_err;
319  }
320 
322  {
323  static int last_err = 0;
325  {
326  if(last_err != curr_err && curr_err)
327  {
328  ROS_ERROR("[ns: %s] xArm Error detected! Code: %d", hw_ns_.c_str(), curr_err);
329  last_err = curr_err;
330  }
331  // test:
332  ROS_ERROR("Need Reset returns true! ctrl_method_: %d, curr_mode: %d, curr_state: %d, curr_err: %d", ctrl_method_, curr_mode, curr_state, curr_err);
333  return true;
334  }
335  else
336  {
337  last_err = 0;
338  return false;
339  }
340  }
341 }
342 
std::vector< float > velocity_cmd_float_
Definition: xarm_hw.h:73
int setState(short state)
hardware_interface::JointStateInterface js_interface_
Definition: xarm_hw.h:89
std::vector< double > position_fdb_
Definition: xarm_hw.h:76
hardware_interface::PositionJointInterface pj_interface_
Definition: xarm_hw.h:91
urdf::ModelInterfaceSharedPtr model_ptr_
Definition: xarm_hw.h:86
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::vector< double > velocity_fdb_
Definition: xarm_hw.h:77
static const int POSE
static const int STOP
int motionEnable(short en)
std::mutex mutex_
Definition: xarm_hw.h:81
std::vector< double > velocity_cmd_
Definition: xarm_hw.h:72
void get_status(int state_mode_err[3])
Definition: xarm_hw.cpp:314
joint_limits_interface::PositionJointSoftLimitsInterface pj_limits_interface_
Definition: xarm_hw.h:97
void enforceLimits(const ros::Duration &period)
hardware_interface::EffortJointInterface ej_interface_
Definition: xarm_hw.h:90
ros::Subscriber pos_sub_
Definition: xarm_hw.h:101
std::vector< float > position_cmd_float_
Definition: xarm_hw.h:71
std::vector< double > effort_cmd_
Definition: xarm_hw.h:74
std::vector< double > position_cmd_
Definition: xarm_hw.h:70
hardware_interface::VelocityJointInterface vj_interface_
Definition: xarm_hw.h:92
xarm_api::XArmROSClient xarm
Definition: xarm_hw.h:84
joint_limits_interface::EffortJointSoftLimitsInterface ej_limits_interface_
Definition: xarm_hw.h:95
virtual void read(const ros::Time &time, const ros::Duration &period)
Definition: xarm_hw.cpp:250
bool getSoftJointLimits(urdf::JointConstSharedPtr urdf_joint, SoftJointLimits &soft_limits)
void pos_fb_cb(const sensor_msgs::JointState::ConstPtr &data)
Definition: xarm_hw.cpp:200
void _reset_limits(void)
Definition: xarm_hw.cpp:218
void state_fb_cb(const xarm_msgs::RobotMsg::ConstPtr &data)
Definition: xarm_hw.cpp:211
const std::string & getNamespace() const
int setMode(short mode)
int veloMoveJoint(const std::vector< float > &jnt_v, bool is_sync=true)
std::vector< double > effort_fdb_
Definition: xarm_hw.h:78
void registerHandle(const JointStateHandle &handle)
const std::string xarm_state_topic
Definition: xarm_hw.h:38
JointHandle getHandle(const std::string &name)
static const int VELO_JOINT
std::vector< std::string > jnt_names_
Definition: xarm_hw.h:69
joint_limits_interface::EffortJointSaturationInterface ej_sat_interface_
Definition: xarm_hw.h:94
static const int START
bool getParam(const std::string &key, std::string &s) const
bool getJointLimits(urdf::JointConstSharedPtr urdf_joint, JointLimits &limits)
static const int SERVO
ROSCPP_DECL void shutdown()
void clientInit(const std::string &robot_ip, ros::NodeHandle &root_nh)
Definition: xarm_hw.cpp:68
void init(ros::NodeHandle &nh)
ControlMethod ctrl_method_
Definition: xarm_hw.h:87
const std::string jnt_state_topic
Definition: xarm_hw.h:37
bool hasParam(const std::string &key) const
std::string hw_ns_
Definition: xarm_hw.h:82
void _register_joint_limits(ros::NodeHandle &root_nh, std::string joint_name, const ControlMethod ctrl_method)
Definition: xarm_hw.cpp:12
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
#define ROS_ERROR(...)
ros::Subscriber state_sub_
Definition: xarm_hw.h:101
joint_limits_interface::VelocityJointSaturationInterface vj_sat_interface_
Definition: xarm_hw.h:98
unsigned int dof_
Definition: xarm_hw.h:68
joint_limits_interface::VelocityJointSoftLimitsInterface vj_limits_interface_
Definition: xarm_hw.h:99
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
joint_limits_interface::PositionJointSaturationInterface pj_sat_interface_
Definition: xarm_hw.h:96
int setServoJ(const std::vector< float > &joint_cmd)
virtual void write(const ros::Time &time, const ros::Duration &period)
Definition: xarm_hw.cpp:255
void _enforce_limits(const ros::Duration &period)
Definition: xarm_hw.cpp:224
virtual bool init(ros::NodeHandle &root_nh, ros::NodeHandle &robot_hw_nh)
Definition: xarm_hw.cpp:142


xarm_controller
Author(s):
autogenerated on Sat May 8 2021 02:51:38