bulk_read_write_node.cpp
Go to the documentation of this file.
1 // Copyright 2021 ROBOTIS CO., LTD.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 /*******************************************************************************
16  * This example is written for DYNAMIXEL X(excluding XL-320) and MX(2.0) series with U2D2.
17  * For other series, please refer to the product eManual and modify the Control Table addresses and other definitions.
18  * To test this example, please follow the commands below.
19  *
20  * Open terminal #1
21  * $ roscore
22  *
23  * Open terminal #2
24  * $ rosrun dynamixel_sdk_examples bulk_read_write_node
25  *
26  * Open terminal #3 (run one of below commands at a time)
27  * $ rostopic pub -1 /bulk_set_item dynamixel_sdk_examples/BulkSetItem "{id1: 1, id2: 2, item1: 'position', item2: 'LED', value1: 1000, value2: 1}"
28  * $ rostopic pub -1 /bulk_set_item dynamixel_sdk_examples/BulkSetItem "{id1: 1, id2: 2, item1: 'LED', item2: 'position', value1: 1, value2: 1000}"
29  * $ rosservice call /bulk_get_item "{id1: 1, id2: 2, item1: 'position', item2: 'LED'}"
30  *
31  * Author: Jaehyun Shim
32 *******************************************************************************/
33 
34 #include <ros/ros.h>
35 
36 #include "std_msgs/String.h"
37 #include "dynamixel_sdk_examples/BulkGetItem.h"
38 #include "dynamixel_sdk_examples/BulkSetItem.h"
40 
41 using namespace dynamixel;
42 
43 // Control table address
44 #define ADDR_TORQUE_ENABLE 64
45 #define ADDR_PRESENT_LED 65
46 #define ADDR_PRESENT_POSITION 132
47 #define ADDR_GOAL_POSITION 116
48 
49 // Protocol version
50 #define PROTOCOL_VERSION 2.0 // Default Protocol version of DYNAMIXEL X series.
51 
52 // Default setting
53 #define DXL1_ID 1 // DXL1 ID
54 #define DXL2_ID 2 // DXL2 ID
55 #define BAUDRATE 57600 // Default Baudrate of DYNAMIXEL X series
56 #define DEVICE_NAME "/dev/ttyUSB0" // [Linux] To find assigned port, use "$ ls /dev/ttyUSB*" command
57 
60 
61 GroupBulkRead groupBulkRead(portHandler, packetHandler);
62 GroupBulkWrite groupBulkWrite(portHandler, packetHandler);
63 
65  dynamixel_sdk_examples::BulkGetItem::Request & req,
66  dynamixel_sdk_examples::BulkGetItem::Response & res)
67 {
68  uint8_t dxl_error = 0;
69  int dxl_comm_result = COMM_TX_FAIL;
70  int dxl_addparam_result = false;
71 
72  // Position Value of X series is 4 byte data. For AX & MX(1.0) use 2 byte data(int16_t) for the Position Value.
73  int32_t position1 = 0;
74  int32_t position2 = 0;
75 
76  // Read Present Position (length : 4 bytes) and Convert uint32 -> int32
77  // When reading 2 byte data from AX / MX(1.0), use read2ByteTxRx() instead.
78  if (req.item1 == "position") {
79  dxl_addparam_result = groupBulkRead.addParam((uint8_t)req.id1, ADDR_PRESENT_POSITION, 4);
80  } else if (req.item1 == "LED") {
81  dxl_addparam_result = groupBulkRead.addParam((uint8_t)req.id1, ADDR_PRESENT_LED, 1);
82  }
83  if (dxl_addparam_result != true) {
84  ROS_ERROR("Failed to addparam to groupBulkRead for Dynamixel ID: %d", req.id1);
85  return 0;
86  }
87 
88  if (req.item2 == "position") {
89  dxl_addparam_result = groupBulkRead.addParam((uint8_t)req.id2, ADDR_PRESENT_POSITION, 4);
90  } else if (req.item2 == "LED") {
91  dxl_addparam_result = groupBulkRead.addParam((uint8_t)req.id2, ADDR_PRESENT_LED, 1);
92  }
93  if (dxl_addparam_result != true) {
94  ROS_ERROR("Failed to addparam to groupBulkRead for Dynamixel ID %d", req.id2);
95  return 0;
96  }
97 
98  uint32_t value1 = 0;
99  uint32_t value2 = 0;
100  dxl_comm_result = groupBulkRead.txRxPacket();
101  if (dxl_comm_result == COMM_SUCCESS) {
102  if (req.item1 == "position") {
103  value1 = groupBulkRead.getData((uint8_t)req.id1, ADDR_PRESENT_POSITION, 4);
104  } else if (req.item2 == "LED") {
105  value1 = groupBulkRead.getData((uint8_t)req.id1, ADDR_PRESENT_POSITION, 4);
106  }
107 
108  if (req.item1 == "position") {
109  value2 = groupBulkRead.getData((uint8_t)req.id2, ADDR_PRESENT_POSITION, 4);
110  } else if (req.item2 == "LED") {
111  value2 = groupBulkRead.getData((uint8_t)req.id2, ADDR_PRESENT_POSITION, 4);
112  }
113 
114  ROS_INFO("getItem : [ID:%d] [%s: %d]", req.id1, req.item1.c_str(), value1);
115  ROS_INFO("getItem : [ID:%d] [%s: %d]", req.id2, req.item2.c_str(), value2);
116  res.value1 = value1;
117  res.value2 = value2;
119  return true;
120  } else {
121  ROS_ERROR("Failed to get position! Result: %d", dxl_comm_result);
123  return false;
124  }
125 }
126 
127 void bulkSetItemCallback(const dynamixel_sdk_examples::BulkSetItem::ConstPtr & msg)
128 {
129  uint8_t dxl_error = 0;
130  int dxl_comm_result = COMM_TX_FAIL;
131  int dxl_addparam_result = false;
132  uint8_t param_goal_position1[4];
133  uint8_t param_goal_position2[4];
134  uint8_t param_goal_led1[1];
135  uint8_t param_goal_led2[1];
136  uint8_t addr_goal_item[2];
137  uint8_t len_goal_item[2];
138 
139  // Position Value of X series is 4 byte data. For AX & MX(1.0) use 2 byte data(uint16_t) for the Position Value.
140  if (msg->item1 == "position") {
141  uint32_t position1 = (unsigned int)msg->value1; // Convert int32 -> uint32
142  param_goal_position1[0] = DXL_LOBYTE(DXL_LOWORD(position1));
143  param_goal_position1[1] = DXL_HIBYTE(DXL_LOWORD(position1));
144  param_goal_position1[2] = DXL_LOBYTE(DXL_HIWORD(position1));
145  param_goal_position1[3] = DXL_HIBYTE(DXL_HIWORD(position1));
146  addr_goal_item[0] = ADDR_GOAL_POSITION;
147  len_goal_item[0] = 4;
148  } else if (msg->item1 == "LED") {
149  uint32_t led1 = (unsigned int)msg->value1; // Convert int32 -> uint32
150  param_goal_led1[0] = led1;
151  addr_goal_item[0] = ADDR_PRESENT_LED;
152  len_goal_item[0] = 1;
153  }
154 
155  if (msg->item2 == "position") {
156  uint32_t position2 = (unsigned int)msg->value2; // Convert int32 -> uint32
157  param_goal_position2[0] = DXL_LOBYTE(DXL_LOWORD(position2));
158  param_goal_position2[1] = DXL_HIBYTE(DXL_LOWORD(position2));
159  param_goal_position2[2] = DXL_LOBYTE(DXL_HIWORD(position2));
160  param_goal_position2[3] = DXL_HIBYTE(DXL_HIWORD(position2));
161  addr_goal_item[1] = ADDR_GOAL_POSITION;
162  len_goal_item[1] = 4;
163  } else if (msg->item2 == "LED") {
164  uint32_t led2 = (unsigned int)msg->value2; // Convert int32 -> uint32
165  param_goal_led2[0] = led2;
166  addr_goal_item[1] = ADDR_PRESENT_LED;
167  len_goal_item[1] = 1;
168  }
169 
170  // Write Goal Position (length : 4 bytes)
171  // When writing 2 byte data to AX / MX(1.0), use write2ByteTxRx() instead.
172  if (msg->item1 == "position") {
173  dxl_addparam_result = groupBulkWrite.addParam((uint8_t)msg->id1, addr_goal_item[0], len_goal_item[0], param_goal_position1);
174  } else if (msg->item1 == "LED") {
175  dxl_addparam_result = groupBulkWrite.addParam((uint8_t)msg->id1, addr_goal_item[0], len_goal_item[0], param_goal_led1);
176  }
177  if (dxl_addparam_result != true) {
178  ROS_ERROR("Failed to addparam to groupBulkWrite for Dynamixel ID: %d", msg->id1);
179  }
180 
181  if (msg->item2 == "position") {
182  dxl_addparam_result = groupBulkWrite.addParam((uint8_t)msg->id2, addr_goal_item[1], len_goal_item[1], param_goal_position2);
183  } else if (msg->item2 == "LED") {
184  dxl_addparam_result = groupBulkWrite.addParam((uint8_t)msg->id2, addr_goal_item[1], len_goal_item[1], param_goal_led2);
185  }
186  if (dxl_addparam_result != true) {
187  ROS_ERROR("Failed to addparam to groupBulkWrite for Dynamixel ID: %d", msg->id2);
188  }
189 
190  dxl_comm_result = groupBulkWrite.txPacket();
191  if (dxl_comm_result == COMM_SUCCESS) {
192  ROS_INFO("setItem : [ID:%d] [%s:%d]", msg->id1, msg->item1.c_str(), msg->value1);
193  ROS_INFO("setItem : [ID:%d] [%s:%d]", msg->id2, msg->item2.c_str(), msg->value2);
194  } else {
195  ROS_INFO("Failed to set position! Result: %d", dxl_comm_result);
196  }
197 
199 }
200 
201 int main(int argc, char ** argv)
202 {
203  uint8_t dxl_error = 0;
204  int dxl_comm_result = COMM_TX_FAIL;
205 
206  if (!portHandler->openPort()) {
207  ROS_ERROR("Failed to open the port!");
208  return -1;
209  }
210 
211  if (!portHandler->setBaudRate(BAUDRATE)) {
212  ROS_ERROR("Failed to set the baudrate!");
213  return -1;
214  }
215 
216  dxl_comm_result = packetHandler->write1ByteTxRx(
217  portHandler, DXL1_ID, ADDR_TORQUE_ENABLE, 1, &dxl_error);
218  if (dxl_comm_result != COMM_SUCCESS) {
219  ROS_ERROR("Failed to enable torque for Dynamixel ID: %d", DXL1_ID);
220  return -1;
221  }
222 
223  dxl_comm_result = packetHandler->write1ByteTxRx(
224  portHandler, DXL2_ID, ADDR_TORQUE_ENABLE, 1, &dxl_error);
225  if (dxl_comm_result != COMM_SUCCESS) {
226  ROS_ERROR("Failed to enable torque for Dynamixel ID: %d", DXL2_ID);
227  return -1;
228  }
229 
230  ros::init(argc, argv, "bulk_read_write_node");
231  ros::NodeHandle nh;
232  ros::ServiceServer bulk_get_item_srv = nh.advertiseService("/bulk_get_item", bulkGetItemCallback);
233  ros::Subscriber bulk_set_item_sub = nh.subscribe("/bulk_set_item", 10, bulkSetItemCallback);
234  ros::spin();
235 
236  portHandler->closePort();
237  return 0;
238 }
#define ADDR_TORQUE_ENABLE
PortHandler * portHandler
#define ADDR_GOAL_POSITION
static PortHandler * getPortHandler(const char *port_name)
virtual bool openPort()=0
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int main(int argc, char **argv)
bool addParam(uint8_t id, uint16_t start_address, uint16_t data_length)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
#define DXL2_ID
#define PROTOCOL_VERSION
#define ADDR_PRESENT_POSITION
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
int COMM_SUCCESS
#define BAUDRATE
#define ADDR_PRESENT_LED
virtual void closePort()=0
#define DEVICE_NAME
#define ROS_INFO(...)
GroupBulkWrite groupBulkWrite(portHandler, packetHandler)
virtual int write1ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint8_t data, uint8_t *error=0)=0
void bulkSetItemCallback(const dynamixel_sdk_examples::BulkSetItem::ConstPtr &msg)
bool bulkGetItemCallback(dynamixel_sdk_examples::BulkGetItem::Request &req, dynamixel_sdk_examples::BulkGetItem::Response &res)
ROSCPP_DECL void spin()
#define DXL1_ID
static PacketHandler * getPacketHandler(float protocol_version=2.0)
def DXL_HIBYTE(w)
def DXL_LOWORD(l)
uint32_t getData(uint8_t id, uint16_t address, uint16_t data_length)
def DXL_HIWORD(l)
virtual bool setBaudRate(const int baudrate)=0
GroupBulkRead groupBulkRead(portHandler, packetHandler)
PacketHandler * packetHandler
#define ROS_ERROR(...)
def DXL_LOBYTE(w)
bool addParam(uint8_t id, uint16_t start_address, uint16_t data_length, uint8_t *data)
int COMM_TX_FAIL


dynamixel_sdk_examples
Author(s): zerom
autogenerated on Fri Apr 16 2021 02:25:58