import sys,os
import math,time
import threading
KP = 2.5
KI = 0.08
KD = 0.3
delta_t = 0.01
target_speed = 0
program_running_flag = False
speed_limit = 100
accel_limit = 10
def getch():
import tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def input_task():
global program_running_flag, target_speed, speed_limit, delta_t
while program_running_flag:
input_key = getch()
if ord(input_key) == 27:
program_running_flag = False
elif ord(input_key) == ord("w"):
target_speed+=1
elif ord(input_key) == ord("s"):
target_speed-=1
elif ord(input_key) == ord('W'):
target_speed += 10
elif ord(input_key) == ord('S'):
target_speed -= 10
elif ord(input_key) == ord(" "):
target_speed = 0
target_speed = target_speed if abs(target_speed)<=speed_limit else math.copysign(speed_limit,target_speed)
time.sleep(delta_t)
def output_task():
global program_running_flag, target_speed, accel_limit, KP, KI, KD, delta_t
erase_str = "\r\033[k"
speed = 0
accel = 0
error_integral = 0
previous_speed_error = 0
while program_running_flag:
speed_error = target_speed-speed
PTerm = KD*speed_error
error_integral += speed_error * delta_t
ITerm = KI*error_integral
error_derivative = (speed_error-previous_speed_error)/delta_t
DTerm = KD * error_derivative
accel = PTerm+ITerm+DTerm
accel = accel if abs(accel)<accel_limit else math.copysign(accel_limit,accel)
speed = speed+accel*delta_t
previous_speed_error = speed_error
display_str = "Target Speed:\t {0:.2f} m/s\tCurrent Speed:\t {1:.2f}m/s\tAccel:\t {2:.2f} m/s^2".format(target_speed,speed,accel)
res = sys.stdout.write(erase_str+display_str)
time.sleep(delta_t)
def main():
global program_running_flag
program_running_flag = True
input_thread = threading.Thread(target=input_task)
input_thread.start()
output_thread = threading.Thread(target=output_task)
output_thread.start()
input_thread.join()
output_thread.join()
main()