-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmotorPID.py
executable file
·90 lines (73 loc) · 1.91 KB
/
motorPID.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
#!/usr/bin/env pythone
# low-level motor handler
import Adafruit_BBIO.PWM as PWM
import Adafruit_BBIO.GPIO as GPIO
import math
######################### MOTOR FUNCTIONS #########################
class motor:
def __init__(self, pin_pwm, pin_for, pin_back, encoder_ref):
self.pin_pwm = pin_pwm
self.pin_for = pin_for
self.pin_back = pin_back
# startup pwm, stop
GPIO.setup(self.pin_for, GPIO.OUT)
GPIO.setup(self.pin_back, GPIO.OUT)
#self.stop()
PWM.start(self.pin_pwm, 0.0)
# motor/pid params
self.kv = 0.1 # TODO
self.kp = 10.0 # TODO
self.ki = 0.0 # TODO
self.kd = 0.0 # TODO
# save encoder class link
self.e = encoder_ref
self.dist = 0;
self.ierror = 0
def stop(self):
PWM.set_duty_cycle(self.pin_pwm, 0)
# set enable pin low
#GPIO.output(self.pin_en, GPIO.LOW)
def setPWMFrequency(self,freq):
PWM.set_frequency(pin_pwm,freq)
def resetPid(self):
self.dist = 0
self.integralReset()
def pid(self,xgoal, vgoal):
# feed-forwards term
ff = self.kv * vgoal
self.dist += self.e.get_delta() * .0203
# pid calcs
error = xgoal-self.dist
derror = 0#-sign(error)*e.v
self.ierror += error
pid_total = self.kp*error + self.ki*self.ierror + self.kd*derror + ff
if pid_total > 9:
pid_total = 9
elif pid_total < -9:
pid_total = -9
# stop motors if close to goal
if math.fabs(error) > 0.25:
self.run(pid_total)
return 0
else:
self.run(0)
return 1
def run(self,volts):
if volts != 0.0:
# volts is signed, -9 to 9
#GPIO.output(self.pin_en, GPIO.HIGH)
if volts > 0:
GPIO.output(self.pin_back, GPIO.HIGH)
GPIO.output(self.pin_for, GPIO.LOW)
else:
GPIO.output(self.pin_back, GPIO.LOW)
GPIO.output(self.pin_for, GPIO.HIGH)
# rescale volts
volts = math.fabs(volts)*100./9.
if (volts > 100):
volts = 100
PWM.set_duty_cycle(self.pin_pwm, volts)
else:
self.stop()
def integralReset(self):
self.ierror = 0