-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathVESCReceive.py
153 lines (130 loc) · 3.77 KB
/
VESCReceive.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
#!/usr/bin/env python3
# Code for Rasberry Pi to interface with a VESC using a Wiimote
import time
import serial
import pyvesc
import sys
from subprocess import Popen, PIPE
from threading import Thread
from queue import Queue, Empty
# Global Variables
POWER_DOWN = ["sudo", "shutdown", "-h", "now"]
# Constants for Accel and Brake
BRAKE_ONE = 10000
BRAKE_TWO = 20000
BRAKE_THREE = 30000
BRAKE_FOUR = 50000
SPEED_ONE = 10000
SPEED_TWO = 20000
SPEED_THREE = 30000
SPEED_FOUR = 50000
STOP = 0
DIV_CONST = 15
SLEEP_TIME = 0.0001
# Create a serial object to send serial messages
ser = serial.Serial(
port='/dev/serial0',
baudrate = 115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
# Function to read input
def enqueueOutput(out, queue):
while True:
lines = out.readline().decode('utf-8')
out.flush()
queue.put(lines)
# Function to simplify the serial output for changing duty cycles
def changeDuty(num):
ser.write(pyvesc.encode(pyvesc.SetDutyCycle(num)))
time.sleep(SLEEP_TIME)
# Function to simplify the serial output for changing brake
def changeBrake(num):
ser.write(pyvesc.encode(pyvesc.SetCurrentBrake(num)))
# Function to simplify the gradual increase of speed if stepping up
def stepUp(speedStart, speedEnd, input):
for i in range(int(speedStart/DIV_CONST), int(speedEnd/DIV_CONST)):
changeDuty(i*DIV_CONST)
try:
newInput = str(queue.get_nowait()).rstrip()
except Empty:
continue
else:
sys.stdout.write(newInput + "\n")
sys.stdout.flush()
if newInput != input:
break
# Starting the input process and thread
process = Popen(['/usr/bin/node', 'pipe.js'], stdout=PIPE)
queue = Queue()
enqueueOutputThread = Thread(target=enqueueOutput, args=(process.stdout, queue))
enqueueOutputThread.daemon = True
enqueueOutputThread.start()
oldInput = ""
go = True
tick = 0
# Motor Control
while True:
# Get new input
try:
newInput = str(queue.get_nowait()).rstrip()
except Empty:
continue
else:
sys.stdout.write(newInput + "\n")
sys.stdout.flush()
# Is it Brake or Accel?
if newInput == "A" and go and tick == 0:
go = False
tick = 4
elif newInput == "A" and not go and tick == 0:
go = True
tick = 4
#Brake Mode
if not go:
changeBrake(10)
if newInput == "DOWN":
changeBrake(BRAKE_ONE)
if newInput == "LEFT":
changeBrake(BRAKE_TWO)
if newInput == "UP":
changeBrake(BRAKE_THREE)
if newInput == "RIGHT":
changeBrake(BRAKE_FOUR)
#Accel Mode
if go:
# Speed 1
if newInput == "DOWN":
changeDuty(SPEED_ONE)
# Speed 2
if newInput == "LEFT":
if oldInput == "DOWN":
stepUp(SPEED_ONE, SPEED_TWO, "LEFT")
else:
changeDuty(SPEED_TWO)
# Speed 3
if newInput == "UP":
if oldInput == "LEFT":
stepUp(SPEED_TWO, SPEED_THREE, "UP")
elif oldInput == "DOWN":
stepUp(SPEED_ONE, SPEED_THREE, "UP")
else:
changeDuty(SPEED_THREE)
# Speed 4
if newInput == "RIGHT":
if oldInput == "UP":
stepUp(SPEED_THREE, SPEED_FOUR, "RIGHT")
elif oldInput == "LEFT":
stepUp(SPEED_TWO, SPEED_FOUR, "RIGHT")
elif oldInput == "DOWN":
stepUp(SPEED_ONE, SPEED_FOUR, "RIGHT")
else:
changeDuty(SPEED_FOUR)
# Emergency off switch
if newInput == "HOME":
changeDuty(STOP)
oldInput = newInput
if tick > 0:
tick -= 1