-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstiffness_algorithm.py
360 lines (260 loc) · 12.4 KB
/
stiffness_algorithm.py
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#!/usr/bin/env python
import os
import numpy as np
import time
import rospy
from dynamixel_sdk import *
from dynamixel_sdk_examples.srv import *
from dynamixel_sdk_examples.msg import *
import math
import matplotlib.pyplot as plt
import pandas as pd
from std_msgs.msg import Float32 #importing library for reading potentiometer
from geometry_msgs.msg import Twist
from rospy.topics import Publisher, Subscriber
if os.name == 'nt':
import msvcrt
def getch():
return msvcrt.getch().decode()
else:
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
def getch():
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
# Control table address
ADDR_TORQUE_ENABLE = 24 # Control table address is different in Dynamixel model
ADDR_GOAL_POSITION = 30
ADDR_PRESENT_POSITION = 36
# Protocol version
PROTOCOL_VERSION = 1.0 # See which protocol version is used in the Dynamixel
# Default setting
DXL_ID = 1 # Dynamixel ID : 1
DXL_ID_2 = 2 # Dynamixel ID : 2
BAUDRATE = 1000000 # Dynamixel default baudrate : 57600
DEVICENAME = '/dev/ttyUSB0' # Check which port is being used on your controller
TORQUE_ENABLE = 1 # Value for enabling the torque
TORQUE_DISABLE = 0 # Value for disabling the torque
DXL_MINIMUM_POSITION_VALUE = 0 # Dynamixel will rotate between this value
DXL_MAXIMUM_POSITION_VALUE = 1000 # and this value (note that the Dynamixel would not move when the position value is out of movable range. Check e-manual about the range of the Dynamixel you use.)
DXL_MOVING_STATUS_THRESHOLD = 5 # Dynamixel moving status threshold
#INITIALIZING GLOBAL VARIABLE
finger_current_position = 0.0 #in metres
finger_current_position_analog_0 = 0.0 # in metres
total_length_potentiometer = 20 #centimeters
total_voltage_potentiometer = 5 #volts
distance_every_volt = total_length_potentiometer / total_voltage_potentiometer
force = []
force_analog_0 = []
distance_id1 = []
finger_position = []
finger_position_analog_0 = []
total_force_gripper = []
portHandler = PortHandler(DEVICENAME)
packetHandler = PacketHandler(PROTOCOL_VERSION)
def potentiometer_read_callback_2(data):
global finger_current_position
global distance_every_volt
finger_current_position = distance_every_volt * data.data / 100
def potentiometer_read_callback(data_0):
global distance_every_volt
global finger_current_position_analog_0
finger_current_position_analog_0 = distance_every_volt * data_0.data / 100
def set_goal_pos_callback(data):
print("Setting Goal Position of ID %s = %s \n" % (data.id, data.position))
dxl_comm_result, dxl_error = packetHandler.write2ByteTxRx(portHandler, data.id, ADDR_GOAL_POSITION, data.position)
def main():
try:
portHandler.openPort()
print("Succeeded to open the port")
except:
print("Failed to open the port")
print("Press any key to terminate...")
getch()
quit()
# Set port baudrate
try:
portHandler.setBaudRate(BAUDRATE)
print("Succeeded to change the baudrate")
except:
print("Failed to change the baudrate")
print("Press any key to terminate...")
getch()
quit()
rospy.sleep(2)
##ENABLING TORQUE
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_TORQUE_ENABLE, TORQUE_ENABLE)
dxl_comm_result_2, dxl_error_2= packetHandler.write1ByteTxRx(portHandler, DXL_ID_2, ADDR_TORQUE_ENABLE, TORQUE_ENABLE)
print(dxl_comm_result, dxl_error)
print(dxl_comm_result_2, dxl_error_2)
if (dxl_comm_result and dxl_comm_result_2 != COMM_SUCCESS):
# if (dxl_comm_result != COMM_SUCCESS):
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
print("%s" % packetHandler.getTxRxResult(dxl_comm_result_2))
print("Press any key to terminate...")
getch()
quit()
elif (dxl_error and dxl_error_2 != 0):
# elif (dxl_error != 0):
print("%s" % packetHandler.getRxPacketError(dxl_error))
# print("%s" % packetHandler.getRxPacketError(dxl_error_2))
print("Press any key to terminate...")
getch()
quit()
else:
print("DYNAMIXELS has been successfully connected")
print("Ready to set Position.")
rospy.init_node('stiffness_algorithm',anonymous=True)
global finger_current_position #important to keep the current position of finger
global finger_current_position_analog_0
potentiometer_topic = '/analog_input00'
potentiometer_topic_2 = '/analog_input01'
sub = rospy.Subscriber(potentiometer_topic, Float32, potentiometer_read_callback)
Sub_2 = rospy.Subscriber(potentiometer_topic_2, Float32, potentiometer_read_callback_2)
topic_position = "/set_position"
pub = rospy.Publisher(topic_position, SetPosition, queue_size=10)
msg_position = SetPosition()
msg_position_2 = SetPosition()
rospy.Subscriber('set_position',SetPosition, set_goal_pos_callback)
time.sleep(.5) #very important to put in as this gives time for the publisher and subcriber to setup
## constant variables for both dynamixels
c_1 = 27.34 #Newton
c_2 = -168.15 # per metre
total_degree = 300.0
total_bits = 1023.0
radius = 25.46/2 #millimeter
length = radius * (total_degree/total_bits) * math.pi / 180
#changing the datatype of the position to Unassigned int according to the required dynamixel motor
position_ID_2 = 0
position_ID_1 = 1023
position_ID_1 = np.int16(position_ID_1)
position_ID_2 = np.int16(position_ID_2)
print("opening the gripper \n")
msg_position.id = 1
msg_position_2.id = 2
msg_position.position = position_ID_1
msg_position_2.position = position_ID_2
pub.publish(msg_position)
pub.publish(msg_position_2)
rospy.sleep(1)
#Making sure that the dynamixel has reached to the extreme position to open gripper
dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read2ByteTxRx(portHandler, DXL_ID, ADDR_PRESENT_POSITION)
dxl_present_position_2, dxl_comm_result_2, dxl_error_2 = packetHandler.read2ByteTxRx(portHandler, DXL_ID_2, ADDR_PRESENT_POSITION)
while (abs(dxl_present_position_2 - position_ID_2) > DXL_MOVING_STATUS_THRESHOLD and abs(dxl_present_position - position_ID_1) > DXL_MOVING_STATUS_THRESHOLD):
pub.publish(msg_position)
pub.publish(msg_position_2)
rospy.sleep(0.5) #important to put it here other before publishing program moves forward
print("Gripper is open press key to continue")
getch()
loop_rate = rospy.Rate(100) # Operating Frequency
dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read2ByteTxRx(portHandler, DXL_ID, ADDR_PRESENT_POSITION)
dxl_present_position_2, dxl_comm_result_2, dxl_error_2 = packetHandler.read2ByteTxRx(portHandler, DXL_ID_2, ADDR_PRESENT_POSITION)
z = 0
# for z in range(0,15,1):
# while(z<1):
## Maximum position at 100 hz = 12.8898 so change in position should be less than that
#
for position_ID_2 in range (0,600,10):
# msg_position.id = 1
msg_position_2.id = 2
# position_ID_1 = position_ID_1 + 10
# msg_position.position = position_ID_1
msg_position_2.position = position_ID_2
pub.publish(msg_position)
pub.publish(msg_position_2)
# rospy.sleep(0.5)
loop_rate.sleep()
# potentiometer_read()
# rospy.sleep(0.5) #very important as this gives time for the motor to rotate
dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read2ByteTxRx(portHandler, DXL_ID, ADDR_PRESENT_POSITION)
dxl_present_position_2, dxl_comm_result_2, dxl_error_2 = packetHandler.read2ByteTxRx(portHandler, DXL_ID_2, ADDR_PRESENT_POSITION)
# rospy.sleep(.5)
print("the current position of motor is ", dxl_present_position)
print("current position of motor ID _2", dxl_present_position_2)
# quit()
# if dxl_present_position_2 < 1025 and dxl_present_position < 1025:
length_dynamixel_ID1 = 1023 - dxl_present_position
current_length_moved_1 = (length * length_dynamixel_ID1)/1000 #metres
#metres and ID1 starts from 15cm mark and reduces from there also the width of the finger is 1 cm till face of magnet
S_i_2 = .121 - (finger_current_position + 0.01 + current_length_moved_1)
current_length_moved_2 = (length * dxl_present_position_2)/1000 #metres
#ID2 starts from 4cm mark also the width of the finger is 1cm till the face of magnet
S_o_2 = finger_current_position - (.043 + .01 + current_length_moved_2)
delta_force = abs((c_1* math.exp(c_2 * S_o_2)) - (c_1* math.exp(c_2 * S_i_2)))
## FOR ANALOG 0 POTENTIOMETER AND FINGER
# motor is already at 4.3 cms and also the width of the finger is 1cm till the face of the magnet
S_o_2_analog0 = finger_current_position_analog_0 - (0.043 + 0.01 + current_length_moved_2)
## motor is already at 4cms and also the width of the finger is 1cm till the face of the magnet
S_i_2_analog0 = .123 - (finger_current_position_analog_0 + 0.01 + current_length_moved_1)
delta_force_analog_0 = abs((c_1* math.exp(c_2 * S_o_2_analog0)) - (c_1* math.exp(c_2 * S_i_2_analog0)))
finger_position_analog_0.append(finger_current_position_analog_0)
finger_position.append(finger_current_position)
#REAL TIME PLOTTING
force_analog_0.append(delta_force_analog_0)
force.append(delta_force)
print("delta force",delta_force)
print("delta force analog 0", delta_force_analog_0)
### GRAPH FOR ANALOG 1 and ANALOG 0
# plt.clf()
# plt.subplot(2,1,1)
# plt.scatter(finger_position,force)
# plt.plot(finger_position,force)
# plt.xlabel('Position of analog 1 finger')
# plt.ylabel("Force applied by analog 0 finger")
# plt.tight_layout()
# plt.draw()
# plt.subplot(2,1,2)
# plt.scatter(finger_position_analog_0,force_analog_0)
# plt.plot(finger_position_analog_0,force_analog_0)
# plt.xlabel('Position of analog 0 finger')
# plt.ylabel("Force applied by analog 0 finger")
# plt.tight_layout()
# plt.draw()
# plt.pause(.0000001)
# break
#Putting threshold for individual finger
if (delta_force > 5 and delta_force_analog_0 > 5):
print("Object has been in touch of both fingers exiting the FOR loop")
break
# else:
# pass
#SAVING DATA IN CSV FILE
# df = pd.DataFrame(list(zip(finger_position,force,finger_position_analog_0,force_analog_0)),columns=['analog_1_finger','force_analog_1','analog_0_finger','force_analog_0'])
# df.to_csv('force_profile.csv', header=True, index=False)
# print(df)
print("press key to exit program")
getch()
print("PROGRAM HAS EXITED")
plt.subplot(2,1,1)
plt.scatter(finger_position,force)
plt.plot(finger_position,force)
plt.xlabel('Position of analog 1 finger')
plt.ylabel("Force applied by analog 1 finger")
plt.tight_layout()
plt.draw()
plt.subplot(2,1,2)
plt.scatter(finger_position_analog_0,force_analog_0)
plt.plot(finger_position_analog_0,force_analog_0)
plt.xlabel('Position of analog 0 finger')
plt.ylabel("Force applied by analog 0 finger")
plt.tight_layout()
plt.draw()
plt.show()
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_TORQUE_ENABLE, TORQUE_DISABLE)
dxl_comm_result_2, dxl_error_2 = packetHandler.write1ByteTxRx(portHandler, DXL_ID_2, ADDR_TORQUE_ENABLE, TORQUE_DISABLE)
portHandler.closePort()
def draw_graph(z):
global distance_id1
global force
plt.cla()
plt.plot(distance_id1,force)
if __name__ == '__main__':
try:
main()
except rospy.ROSInterruptException:
rospy.loginfo("node terminated.")