denso_robot_hw.cpp
Go to the documentation of this file.
1 
25 #include <string.h>
26 #include <sstream>
28 
29 #define RAD2DEG(x) ((x) * 180.0 / M_PI)
30 #define DEG2RAD(x) ((x) / 180.0 * M_PI)
31 
32 #define M2MM(x) ((x) * 1000.0)
33 #define MM2M(x) ((x) / 1000.0)
34 
35 namespace denso_robot_control
36 {
37 
39  {
40  memset(m_cmd, 0, sizeof(m_cmd));
41  memset(m_pos, 0, sizeof(m_pos));
42  memset(m_vel, 0, sizeof(m_vel));
43  memset(m_eff, 0, sizeof(m_eff));
44  memset(m_type, 0, sizeof(m_type));
45  m_joint.resize(JOINT_MAX);
46 
47  m_eng = boost::make_shared<DensoRobotCore>();
48  m_ctrl.reset();
49  m_rob.reset();
50  m_varErr.reset();
51 
52  m_robName = "";
53  m_robJoints = 0;
54  m_sendfmt = DensoRobotRC8::SENDFMT_MINIIO
55  | DensoRobotRC8::SENDFMT_HANDIO;
56  m_recvfmt = DensoRobotRC8::RECVFMT_POSE_PJ
57  | DensoRobotRC8::RECVFMT_MINIIO
58  | DensoRobotRC8::RECVFMT_HANDIO;
59  }
60 
62  {
63 
64  }
65 
67  {
68  ros::NodeHandle nh;
69 
70  if (!nh.getParam("robot_name", m_robName)) {
71  ROS_WARN("Failed to get robot_name parameter.");
72  }
73 
74  if (!nh.getParam("robot_joints", m_robJoints)) {
75  ROS_WARN("Failed to get robot_joints parameter.");
76  }
77 
78  for (int i = 0; i < m_robJoints; i++) {
79  std::stringstream ss;
80  ss << "joint_" << i+1;
81 
82  if (!nh.getParam(ss.str(), m_type[i])) {
83  ROS_WARN("Failed to get joint_%d parameter.", i+1);
84  ROS_WARN("It was assumed revolute type.");
85  m_type[i] = 1;
86  }
87 
88  hardware_interface::JointStateHandle state_handle(ss.str(),
89  &m_pos[i], &m_vel[i], &m_eff[i]);
90  m_JntStInterface.registerHandle(state_handle);
91 
93  m_JntStInterface.getHandle(ss.str()), &m_cmd[i]);
95  }
96 
97  int armGroup = 0;
98  if (!nh.getParam("arm_group", armGroup)) {
99  ROS_INFO("Use arm group 0.");
100  armGroup = 0;
101  }
102 
103  int format = 0;
104  if(nh.getParam("send_format", format)) {
105  m_sendfmt = format;
106  }
107 
108  format = 0;
109  if(nh.getParam("recv_format", format)) {
110  m_recvfmt = format;
111  }
112  switch(m_recvfmt & DensoRobotRC8::RECVFMT_POSE) {
113  case DensoRobotRC8::RECVFMT_POSE_J:
114  case DensoRobotRC8::RECVFMT_POSE_PJ:
115  case DensoRobotRC8::RECVFMT_POSE_TJ:
116  break;
117  default:
118  ROS_WARN("Recieve format has to contain joint.");
119  m_recvfmt = ((m_recvfmt & ~DensoRobotRC8::RECVFMT_POSE)
120  | DensoRobotRC8::RECVFMT_POSE_J);
121  break;
122  }
123 
126 
127  HRESULT hr = m_eng->Initialize();
128  if(FAILED(hr)) {
129  ROS_ERROR("Failed to connect real controller. (%X)", hr);
130  return hr;
131  }
132 
133  m_ctrl = m_eng->get_Controller();
134 
135  DensoRobot_Ptr pRob;
136  hr = m_ctrl->get_Robot(DensoBase::SRV_ACT, &pRob);
137  if(FAILED(hr)) {
138  ROS_ERROR("Failed to connect real robot. (%X)", hr);
139  return hr;
140  }
141 
142  m_rob = boost::dynamic_pointer_cast<DensoRobotRC8>(pRob);
143 
144  hr = CheckRobotType();
145  if(FAILED(hr)) {
146  ROS_ERROR("Invalid robot type.");
147  return hr;
148  }
149 
150  m_rob->ChangeArmGroup(armGroup);
151 
152  hr = m_rob->ExecCurJnt(m_joint);
153  if(FAILED(hr)) {
154  ROS_ERROR("Failed to get current joint. (%X)", hr);
155  return hr;
156  }
157 
158  hr = m_ctrl->AddVariable("@ERROR_CODE");
159  if(SUCCEEDED(hr)) {
160  hr = m_ctrl->get_Variable("@ERROR_CODE", &m_varErr);
161  }
162  if(FAILED(hr)) {
163  ROS_ERROR("Failed to get @ERROR_CODE object. (%X)", hr);
164  return hr;
165  }
166 
167  {
168  // Clear Error
169  VARIANT_Ptr vntVal(new VARIANT());
170  vntVal->vt = VT_I4; vntVal->lVal = 0L;
171  hr = m_varErr->ExecPutValue(vntVal);
172  if(FAILED(hr)) {
173  ROS_ERROR("Failed to clear error. (%X)", hr);
174  return hr;
175  }
176  }
177 
178  hr = m_rob->AddVariable("@SERVO_ON");
179  if(SUCCEEDED(hr)) {
180  DensoVariable_Ptr pVar;
181  hr = m_rob->get_Variable("@SERVO_ON", &pVar);
182  if(SUCCEEDED(hr)) {
183  VARIANT_Ptr vntVal(new VARIANT());
184  vntVal->vt = VT_BOOL;
185  vntVal->boolVal = VARIANT_TRUE;
186  hr = pVar->ExecPutValue(vntVal);
187  }
188  }
189  if(FAILED(hr)) {
190  ROS_ERROR("Failed to motor on. (%X)", hr);
191  return hr;
192  }
193 
194  m_rob->put_SendFormat(m_sendfmt);
195  m_sendfmt = m_rob->get_SendFormat();
196 
197  m_rob->put_RecvFormat(m_recvfmt);
198  m_recvfmt = m_rob->get_RecvFormat();
199 
200  m_subChangeMode = nh.subscribe<Int32>(
201  "ChangeMode", 1, &DensoRobotHW::Callback_ChangeMode, this);
202  m_pubCurMode = nh.advertise<Int32>("CurMode", 1);
203 
204  hr = ChangeModeWithClearError(DensoRobotRC8::SLVMODE_SYNC_WAIT
205  | DensoRobotRC8::SLVMODE_POSE_J);
206  if(FAILED(hr)) {
207  ROS_ERROR("Failed to change to slave mode. (%X)", hr);
208  return hr;
209  }
210 
211  return S_OK;
212  }
213 
215  {
216  HRESULT hr = m_eng->ChangeMode(mode, mode == DensoRobotRC8::SLVMODE_NONE);
217  if(FAILED(hr)) {
218  // Clear Error
219  VARIANT_Ptr vntVal(new VARIANT());
220  vntVal->vt = VT_I4; vntVal->lVal = 0L;
221  m_varErr->ExecPutValue(vntVal);
222  }
223 
224  Int32 msg;
225  msg.data = m_eng->get_Mode();
226  m_pubCurMode.publish(msg);
227 
228  if(msg.data == DensoRobotRC8::SLVMODE_NONE) {
237  }
238  else
239  {
240  ros::NodeHandle nh;
241 
242  if(m_sendfmt & DensoRobotRC8::SENDFMT_HANDIO)
243  {
244  m_subHandIO = nh.subscribe<Int32>(
245  "Write_HandIO", 1, &DensoRobotHW::Callback_HandIO, this);
246  }
247  if(m_sendfmt & DensoRobotRC8::SENDFMT_MINIIO)
248  {
249  m_subMiniIO = nh.subscribe<Int32>(
250  "Write_MiniIO", 1, &DensoRobotHW::Callback_MiniIO, this);
251  }
252  if(m_sendfmt & DensoRobotRC8::SENDFMT_USERIO)
253  {
254  m_subSendUserIO = nh.subscribe<UserIO>(
255  "Write_SendUserIO", 1, &DensoRobotHW::Callback_SendUserIO, this);
256  }
257  if(m_recvfmt & DensoRobotRC8::RECVFMT_HANDIO)
258  {
259  m_pubHandIO = nh.advertise<Int32>("Read_HandIO", 1);
260  }
261  if(m_recvfmt & DensoRobotRC8::RECVFMT_CURRENT)
262  {
263  m_pubCurrent = nh.advertise<Float64MultiArray>("Read_Current", 1);
264  }
265  if(m_recvfmt & DensoRobotRC8::RECVFMT_MINIIO)
266  {
267  m_pubMiniIO = nh.advertise<Int32>("Read_MiniIO", 1);
268  }
269  if(m_recvfmt & DensoRobotRC8::RECVFMT_USERIO)
270  {
271  m_subRecvUserIO = nh.subscribe<UserIO>(
272  "Write_RecvUserIO", 1, &DensoRobotHW::Callback_RecvUserIO, this);
273  m_pubRecvUserIO = nh.advertise<UserIO>("Read_RecvUserIO", 1);
274  }
275  }
276 
277  return hr;
278  }
279 
280  void DensoRobotHW::Callback_ChangeMode(const Int32::ConstPtr& msg)
281  {
282  boost::mutex::scoped_lock lockMode(m_mtxMode);
283 
284  ROS_INFO("Change to mode %d.", msg->data);
285  HRESULT hr = ChangeModeWithClearError(msg->data);
286  if(FAILED(hr)) {
287  ROS_ERROR("Failed to change mode. (%X)", hr);
288  }
289  }
290 
292  {
293  DensoVariable_Ptr pVar;
294  VARIANT_Ptr vntVal(new VARIANT());
295  std::string strTypeName = "@TYPE_NAME";
296 
297  HRESULT hr = m_rob->AddVariable(strTypeName);
298  if(SUCCEEDED(hr)) {
299  m_rob->get_Variable(strTypeName, &pVar);
300  hr = pVar->ExecGetValue(vntVal);
301  if(SUCCEEDED(hr)) {
302  strTypeName = DensoBase::ConvertBSTRToString(vntVal->bstrVal);
303  if(strncmp(m_robName.c_str(), strTypeName.c_str(),
304  (m_robName.length() < strTypeName.length())
305  ? m_robName.length() : strTypeName.length()))
306  {
307  hr = E_FAIL;
308  }
309  }
310  }
311 
312  return hr;
313  }
314 
316  {
317  boost::mutex::scoped_lock lockMode(m_mtxMode);
318 
319  if(m_eng->get_Mode() == DensoRobotRC8::SLVMODE_NONE) {
320  HRESULT hr = m_rob->ExecCurJnt(m_joint);
321  if(FAILED(hr)) {
322  ROS_ERROR("Failed to get current joint. (%X)", hr);
323  }
324  }
325 
326  for(int i = 0; i < m_robJoints; i++) {
327  switch(m_type[i]){
328  case 0: // prismatic
329  m_pos[i] = MM2M(m_joint[i]);
330  break;
331  case 1: // revolute
332  m_pos[i] = DEG2RAD(m_joint[i]);
333  break;
334  case -1: // fixed
335  default:
336  m_pos[i] = 0.0;
337  break;
338  }
339  }
340  }
341 
343  {
344  boost::mutex::scoped_lock lockMode(m_mtxMode);
345 
346  if(m_eng->get_Mode() != DensoRobotRC8::SLVMODE_NONE) {
347  std::vector<double> pose;
348  pose.resize(JOINT_MAX);
349 
350  for(int i = 0; i < m_robJoints; i++) {
351  switch(m_type[i]){
352  case 0: // prismatic
353  pose[i] = M2MM(m_cmd[i]);
354  break;
355  case 1: // revolute
356  pose[i] = RAD2DEG(m_cmd[i]);
357  break;
358  case -1: // fixed
359  default:
360  pose[i] = 0.0;
361  break;
362  }
363  }
364 
365  HRESULT hr = m_rob->ExecSlaveMove(pose, m_joint);
366  if(SUCCEEDED(hr)) {
367  if(m_recvfmt & DensoRobotRC8::RECVFMT_HANDIO)
368  {
369  Int32 msg;
370  msg.data = m_rob->get_HandIO();
371  m_pubHandIO.publish(msg);
372  }
373  if(m_recvfmt & DensoRobotRC8::RECVFMT_CURRENT)
374  {
375  Float64MultiArray msg;
376  m_rob->get_Current(msg.data);
377  m_pubCurrent.publish(msg);
378  }
379  if(m_recvfmt & DensoRobotRC8::RECVFMT_MINIIO)
380  {
381  Int32 msg;
382  msg.data = m_rob->get_MiniIO();
383  m_pubMiniIO.publish(msg);
384  }
385  if(m_recvfmt & DensoRobotRC8::RECVFMT_USERIO)
386  {
387  UserIO msg;
388  m_rob->get_RecvUserIO(msg);
390  }
391  }
392  else if(FAILED(hr) && (hr != E_BUF_FULL)) {
393  ROS_ERROR("Failed to write. (%X)", hr);
394 
395  VARIANT_Ptr vntVal(new VARIANT());
396  hr = m_varErr->ExecGetValue(vntVal);
397  if(FAILED(hr) || (vntVal->lVal != 0)) {
398  ROS_ERROR("Automatically change to normal mode.");
399  ChangeModeWithClearError(DensoRobotRC8::SLVMODE_NONE);
400  }
401  }
402  }
403  }
404 
405  void DensoRobotHW::Callback_MiniIO(const Int32::ConstPtr& msg)
406  {
407  m_rob->put_MiniIO(msg->data);
408  }
409 
410  void DensoRobotHW::Callback_HandIO(const Int32::ConstPtr& msg)
411  {
412  m_rob->put_HandIO(msg->data);
413  }
414 
415  void DensoRobotHW::Callback_SendUserIO(const UserIO::ConstPtr& msg)
416  {
417  m_rob->put_SendUserIO(*msg.get());
418  }
419 
420  void DensoRobotHW::Callback_RecvUserIO(const UserIO::ConstPtr& msg)
421  {
422  m_rob->put_RecvUserIO(*msg.get());
423  }
424 
425 }
#define RAD2DEG(x)
void read(ros::Time, ros::Duration)
void publish(const boost::shared_ptr< M > &message) const
#define VARIANT_TRUE
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void Callback_RecvUserIO(const UserIO::ConstPtr &msg)
#define S_OK
#define JOINT_MAX
HRESULT ChangeModeWithClearError(int mode)
void write(ros::Time, ros::Duration)
#define FAILED(hr)
#define ROS_WARN(...)
#define E_BUF_FULL
VT_I4
#define E_FAIL
int32_t HRESULT
VT_BOOL
#define ROS_INFO(...)
#define M2MM(x)
hardware_interface::JointStateInterface m_JntStInterface
boost::interprocess::unique_ptr< VARIANT, variant_deleter > VARIANT_Ptr
#define SUCCEEDED(hr)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void registerHandle(const JointStateHandle &handle)
hardware_interface::PositionJointInterface m_PosJntInterface
#define MM2M(x)
JointStateHandle getHandle(const std::string &name)
void Callback_SendUserIO(const UserIO::ConstPtr &msg)
std::vector< double > m_joint
bool getParam(const std::string &key, std::string &s) const
void Callback_HandIO(const Int32::ConstPtr &msg)
void Callback_MiniIO(const Int32::ConstPtr &msg)
#define ROS_ERROR(...)
#define DEG2RAD(x)
void Callback_ChangeMode(const Int32::ConstPtr &msg)


denso_robot_control
Author(s): DENSO WAVE INCORPORATED
autogenerated on Mon Jun 10 2019 13:12:33