-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
211 lines (168 loc) · 7.91 KB
/
main.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
#Libraries that we need to import before we start a program.
import os
import serial
import struct
import csv
import os
import time
import keyboard
import matplotlib.pyplot as plot
import numpy as np
#If you find no module found, please install the module using pip installer.
#Arduino port refers to the USB port connected to our PC. It may vary from PC to PC. It is always a good practice to check for PORTID from Ardiuno Application
arduino_port = "COM5"
baud= 9600
samples=200
print_labels=True
impedances= []
position=[]
#Connecting the ardiuno port to this particular program
ser= serial.Serial(arduino_port, baud)
print("Connected to Arduino port:" +arduino_port)
#To get a put character
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
#Default position control program to control Dyamixel Motors
from dynamixel_sdk import * # Uses Dynamixel SDK library
# Control table address
ADDR_PRO_TORQUE_ENABLE = 64 # Control table address is different in Dynamixel model
ADDR_PRO_GOAL_POSITION = 116
ADDR_PRO_PRESENT_POSITION = 132
# Protocol version
PROTOCOL_VERSION = 2.0 # See which protocol version is used in the Dynamixel
# Default setting
DXL_ID = 2 # Dynamixel ID : 1
BAUDRATE = 1000000 # Dynamixel default baudrate : 57600
DEVICENAME = 'COM10' # Check which port is being used on your controller
# ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*"
TORQUE_ENABLE = 1 # Value for enabling the torque
TORQUE_DISABLE = 0 # Value for disabling the torque
DXL_MINIMUM_POSITION_VALUE = 2382 # Dynamixel will rotate between this value
DXL_MAXIMUM_POSITION_VALUE = 3647 # 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 = 20 # Dynamixel moving status threshold
index = 0
dxl_goal_position = [DXL_MINIMUM_POSITION_VALUE, DXL_MAXIMUM_POSITION_VALUE] # Goal position
# Initialize PortHandler instance
# Set the port path
# Get methods and members of PortHandlerLinux or PortHandlerWindows
portHandler = PortHandler(DEVICENAME)
# Initialize PacketHandler instance
# Set the protocol version
# Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler
packetHandler = PacketHandler(PROTOCOL_VERSION)
# Open port
if portHandler.openPort():
print("Succeeded to open the port")
else:
print("Failed to open the port")
print("Press any key to terminate...")
getch()
quit()
# Set port baudrate
if portHandler.setBaudRate(BAUDRATE):
print("Succeeded to change the baudrate")
else:
print("Failed to change the baudrate")
print("Press any key to terminate...")
getch()
quit()
# Enable Dynamixel Torque
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
elif dxl_error != 0:
print("%s" % packetHandler.getRxPacketError(dxl_error))
else:
print("Dynamixel has been successfully connected")
#Start of a while loop, that means the program keeps running until we force stop it.
while 1:
#Simple UI to select options.
keypress=input("1. Calibrate \n2.Measure\n3.Stop \n Enter Options:")
if keypress=="1":
n=2 #In case of calibration the motors moves from Current Postion -> Goal Positon (Extreme End_Right) -> Goal_Position (Extreme_left)
elif keypress=="2" :
n=10 #Measure by default runs 5times both the sides, thats why the n is set to 10. The motor rotates back and forth between two Goal Positions.
elif keypress=="3" :
break #Break- Breaks the while loop
else:
print("Enter valid input")
n=0
i=0
#The Nested while loop is used to move the motor to the both ends.
while i<n: #Until the condition is satisfed, the end effectors keep moving in both the directions. i is set to 0 and n value is recieved from the above if-else condition.
# Write goal position
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL_ID, ADDR_PRO_GOAL_POSITION, dxl_goal_position[index])
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
elif dxl_error != 0:
print("%s" % packetHandler.getRxPacketError(dxl_error))
i=i+1
while 1:
print("%s" % packetHandler.getRxPacketError(dxl_error))
# Read present position
#The below function gives data of the present position.
dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read4ByteTxRx(portHandler, DXL_ID, ADDR_PRO_PRESENT_POSITION)
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
elif dxl_error != 0:
print("%s" % packetHandler.getRxPacketError(dxl_error))
print("[ID:%03d] GoalPos:%03d PresPos:%03d" % (DXL_ID, dxl_goal_position[index], dxl_present_position))
if not abs(dxl_goal_position[index] - dxl_present_position) > DXL_MOVING_STATUS_THRESHOLD:
break
#At this point, The program reads the line from Ardiuno serial monitor
getData= str(ser.readline(), 'utf-8')
data=getData[0:][:-1]
#Condition to check is the first 10 letters start with Impedance.
if data[:10]=="Impedance:":
#impedance values is something after 10 letters
impedance=data[10:]
#Convert string to float
impedance=float(impedance)/1000
#Print the values of impedance
print(impedance)
#Appended to Array/List To understand, what list is CHECK: https://www.w3schools.com/python/python_lists.asp
impedances.append(impedance)
#Converting the position to Angle
angle=dxl_present_position/11.37647058823529
print(angle)
#Appending the angle to data to an List
position.append(angle)
if impedance!=0:
#Writing data to a csv file for references in the future
with open("Impedance_values.csv", "w") as csv_file:
writer = csv.writer(csv_file, delimiter= ';')
writer.writerow((impedance,dxl_present_position))
# Change goal position
#Ones the goal position is reached, we need to switch sides.
if index == 0:
index = 1
else:
index = 0
print("Data collection complete!")
# Disable Dynamixel Torque (Disconnect Motor from the program)
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
if dxl_comm_result != COMM_SUCCESS:
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
elif dxl_error != 0:
print("%s" % packetHandler.getRxPacketError(dxl_error))
# Close Ardiuno ports
portHandler.closePort()
#Plot a graph between Position (X-Axis) vs Impedance(Y-axis)
plot.scatter(position, impedances)
plot.title('Impedance vs position')
plot.xlabel('position')
plot.ylabel('Impedance (KOhms)')
plot.show()