-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvelControlEndEffector.cpp
More file actions
144 lines (120 loc) · 5.56 KB
/
velControlEndEffector.cpp
File metadata and controls
144 lines (120 loc) · 5.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// need to look at the control table from the robotis website to get the control table location for each motor for the velocity control RAM address
// for eg: if using the XL430-W250 motor, control table is at https://emanual.robotis.com/docs/en/dxl/x/xl430-w250/
//Velocity control mode is the most appropriate for end effector control as multiple rotations of the motor are required to pull the control cables to the desired position.
//Test by altering the time of rotation to dial in the time for the gripper to close at each velocity.
#include <ros/ros.h>
#include "std_msgs/String.h"
#include "dynamixel_sdk/dynamixel_sdk.h"
using namespace dynamixel;
// Control table address
#define ADDR_OPERATING_MODE 11
//Set operating mode to 1 for velocity control mode(wheel mode) and 3 for position control mode(joint mode)
#define ADDR_TORQUE_ENABLE 64
#define ADDR_PRESENT_LED 65
#define ADDR_GOAL_POSITION 116
#define ADDR_PRESENT_POSITION 132
#define ADDR_GOAL_VELOCITY 104
#define ADDR_PRESENT_VELOCITY 128
// Protocol version
#define PROTOCOL_VERSION 2.0 // Default Protocol version of DYNAMIXEL X series.
// Default setting
#define DXL1_ID 14 // set this value to the identifier of the end effector motor.
#define BAUDRATE 57600 // Default Baudrate of DYNAMIXEL X series
//set up fixed mount point for the device(U2d2), this is the same as the one set in the udev rules file.
#define DEVICE_NAME "/dev/ttyUSB0" // [Linux] To find assigned port, use "$ ls /dev/ttyUSB*" command
bool getPresentPositionCallback(
dynamixel_sdk_examples::GetPosition::Request & req,
dynamixel_sdk_examples::GetPosition::Response & res)
{
uint8_t dxl_error = 0;
int dxl_comm_result = COMM_TX_FAIL;
// Position Value of X series is 4 byte data. For AX & MX(1.0) use 2 byte data(int16_t) for the Position Value.
int32_t position = 0;
// Read Present Position (length : 4 bytes) and Convert uint32 -> int32
// When reading 2 byte data from AX / MX(1.0), use read2ByteTxRx() instead.
dxl_comm_result = packetHandler->read4ByteTxRx(
portHandler, (uint8_t)req.id, ADDR_PRESENT_POSITION, (uint32_t *)&position, &dxl_error);
if (dxl_comm_result == COMM_SUCCESS) {
ROS_INFO("getPosition : [ID:%d] -> [POSITION:%d]", req.id, position);
res.position = position;
return true;
} else {
ROS_INFO("Failed to get position! Result: %d", dxl_comm_result);
return false;
}
}
bool getPresentVelocityCallback(
flo_humanoid_defs::GetJointVelocity::Request & req,
flo_humanoid_defs::GetJointVelocity::Response & res)
{
uint8_t dxl_error = 0;
int dxl_comm_result = COMM_TX_FAIL;
// Velocity Value of X series is 4 byte data.
int32_t velocity = 0;
// Read Present Velocity (length : 4 bytes) and Convert uint32 -> int32
dxl_comm_result = packetHandler->read4ByteTxRx(
portHandler, (uint8_t)req.id, ADDR_PRESENT_VELOCITY, (uint32_t *)&velocity, &dxl_error);
if (dxl_comm_result == COMM_SUCCESS) {
ROS_INFO("getPosition : [ID:%d] -> [VELOCITY:%d]", req.id, velocity);
res.velocity = velocity;
return true;
} else {
ROS_INFO("Failed to get velocity! Result: %d", dxl_comm_result);
return false;
}
}
void setVelocityCallback(const flo_humanoid_defs::SetJointVelocity::ConstPtr & msg)
{
uint8_t dxl_error = 0;
int dxl_comm_result = COMM_TX_FAIL;
// Position Value of X series is 4 byte data.
// The usefulness of this information is yet undecided
//Do testing with the gripper to figure out if we need to stop the motor at the end position (closed arm) or maintain velocity command.
uint32_t position = (unsigned int)msg->position; // Convert int32 -> uint32
// Write Goal Velocity (length : 4 bytes)
uint32_t velocity = (unsigned int)msg->velocity; // Convert int32 -> uint32
// Write Goal Velocity (length : 4 bytes)
//This variable is going to be used to store the
dxl_comm_result = packetHandler->write4ByteTxRx(
portHandler, (uint8_t)msg->id, ADDR_GOAL_ ADDR_GOAL_VELOCITY, velocity, &dxl_error);
if (dxl_comm_result == COMM_SUCCESS) {
ROS_INFO("setEndEffVelocity : [ID:%d] [VELOCITY:%d]", msg->id, msg->velocity);
} else {
ROS_ERROR("Failed to set end effector velocity! Result: %d", dxl_comm_result);
}
}
int main(int argc, char ** argv)
{
uint8_t dxl_error = 0;
int dxl_comm_result = COMM_TX_FAIL;
portHandler = PortHandler::getPortHandler(DEVICE_NAME);
packetHandler = PacketHandler::getPacketHandler(PROTOCOL_VERSION);
if (!portHandler->openPort()) {
ROS_ERROR("Failed to open the port!");
return -1;
}
if (!portHandler->setBaudRate(BAUDRATE)) {
ROS_ERROR("Failed to set the baudrate!");
return -1;
}
dxl_comm_result = packetHandler->write1ByteTxRx(
portHandler, DXL1_ID, ADDR_TORQUE_ENABLE, 1, &dxl_error);
if (dxl_comm_result != COMM_SUCCESS) {
ROS_ERROR("Failed to enable torque for Dynamixel ID %d", DXL1_ID);
return -1;
}
dxl_comm_result = packetHandler->write1ByteTxRx(
portHandler, DXL1_ID, ADDR_OPERATING_MODE, 1, &dxl_error);
if (dxl_comm_result != COMM_SUCCESS) {
ROS_ERROR("Failed to change operating mode to velocity control for Dynamixel ID %d", DXL1_ID);
return -1;
}
ros::init(argc, argv, "read_write_node");
ros::NodeHandle nh;
ros::ServiceServer get_position_srv = nh.advertiseService("/get_position", getPresentPositionCallback);
ros::ServiceServer get_velocity_srv = nh.advertiseService("/get_velocity", getPresentVelocityCallback);
ros::Subscriber set_velocity_sub = nh.subscribe("/set_velocity", 10, setVelocityCallback);
ros::spin();
portHandler->closePort();
return 0;
}