Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 1 | |||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
|
For the Fall '23 ELEC 424 Final Project, the team was tasked with creating an autonomous RC car - functionally, the car has the two main capabilities:
- accurately follow a defined lane
- stop when it detects a red box in its path
The autonomous processing and decision making on the car was performed by a BeagleBone AI-64 and the input data was collected from a single webcam. The car defaults to operating in the lane-keeping state and when it detects a red box in its path, it switches to a 'stop and wait' state. After a fixed period of time, the car will revert to the lane-keeping state and continue moving.
As we were referencing previous autonomous work done by Instructable's user 'raja_961', the primary challenge in this project was implementing lower-level functionality such as the speed encoder as well as porting the reference code to work on a BBAI64.
The speed encoder is installed on the shaft of the wheels and essentially measures how fast the wheels are rotating. This information was recorded using a Linux device driver. It was then translated to speed units in Python before being used in a feedback network to control the speed of the car.
User raja_961, "Autonomous Lane-Keeping Car Using Raspberry Pi and OpenCV". Instructables. URL: https://www.instructables.com/Autonomous-Lane-Keeping-Car-Using-Raspberry-Pi-and/Setting Resolution and Gain Parameters
Tuning the Proportional and Derivative gain parameters was a process of trial-and-error. The values were varied until the car was not only able to quickly correct rising error (i.e. responsively follow turns in the lane) but also did not overshoot when correcting the error. The selected values were k_p = 0.2 and k_d = k_p * 0.1
The resolution of the camera was also adjusted to lie in the sweet spot where it was low enough to allow fast processing on the BBAI64 while still retaining enough feature details required for accurate lane-keeping and stop box detection. The chosen resolution was 320x240.
Detecting Stop BoxThe stop-box detection was done using 4 corner windows that covered the volume of red in HSV. 'Slicing' a region of the HSV cylinder that contains all the red values, the 4 windows were situated in the top and bottom corners of the left and right edges. The number of red pixels in the camera frame was computed using the cv.inRange and cv.countNonZero functions:
left_lower_red = np.array([0, 40, 100], dtype="uint8")
left_upper_red = np.array([25, 130, 200], dtype="uint8")
right_lower_red = np.array([150, 40, 100], dtype="uint8")
right_upper_red = np.array([200, 130, 200], dtype="uint8")
........
left_mask = cv2.inRange(frame, left_lower_red, left_upper_red)
right_mask = cv2.inRange(frame, right_lower_red, right_upper_red)
mask = cv2.bitwise_or(left_mask, right_mask)
num_red_px = cv2.countNonZero(mask)
If the number of red pixels is higher than the stop threshold(=1800), it triggers the detection of the stop box.
PlotsThe plot above shows the error, steering PWM, and speed PWM over the course of the car's journey through the entire course. Particularly over frames 100-200 and 500-600, we can see that the steering PWM has a distinct relationship with the error as the algorithm tries to correct to the error.
The plot above shows the same error along with the proportional and derivative response - also plotted over the path traversed by the car. While the derivative response varies seemingly erratically, the proportional game follows the error very linearly as expected.
Assembled Car and Video Demo:'''
ELEC 424 Final Project - Autonomous Lanekeeping RC Car
Team YoungerWoods (ft. The NicoMobile)
GitHub Repo:
https://github.com/nicorossirice/comp424-FinalProject/tree/main
Hackster Webpage:
https://www.hackster.io/team-youngerwoods/the-nicomobile-83caa9
Used the following reference code:
https://www.instructables.com/Autonomous-Lane-Keeping-Car-Using-Raspberry-Pi-and/
https://www.hackster.io/really-bad-idea/autonomous-path-following-car-6c4992
'''
import math
import signal
import time
import cv2
import matplotlib.pyplot as plt
import numpy as np
from pwm_control import PWMControl
''' BLUE LINE DETECTION '''
def detect_edges(frame):
# filter for blue lane lines
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#cv2.imshow("HSV",hsv)
lower_blue = np.array([90, 120, 0], dtype = "uint8")
upper_blue = np.array([150, 255, 255], dtype="uint8")
mask = cv2.inRange(hsv,lower_blue,upper_blue)
#cv2.imshow("mask",mask)
# detect edges
edges = cv2.Canny(mask, 50, 100)
#cv2.imshow("edges",edges)
return edges
def region_of_interest(edges):
height, width = edges.shape
mask = np.zeros_like(edges)
# only focus lower half of the screen
polygon = np.array([[
(0, height),
(0, height/2),
(width , height/2),
(width , height),
]], np.int32)
cv2.fillPoly(mask, polygon, 255)
cropped_edges = cv2.bitwise_and(edges, mask)
# cv2.imshow("roi",cropped_edges)
return cropped_edges
def detect_line_segments(cropped_edges):
rho = 1
theta = np.pi / 180
min_threshold = 10
line_segments = cv2.HoughLinesP(cropped_edges, rho, theta, min_threshold,
np.array([]), minLineLength=5, maxLineGap=150)
return line_segments
def average_slope_intercept(frame, line_segments):
lane_lines = []
if line_segments is None:
print("no line segments detected")
return lane_lines
height, width,_ = frame.shape
left_fit = []
right_fit = []
boundary = 1/3
left_region_boundary = width * (1 - boundary)
right_region_boundary = width * boundary
for line_segment in line_segments:
for x1, y1, x2, y2 in line_segment:
if x1 == x2:
print("skipping vertical lines (slope = infinity")
continue
fit = np.polyfit((x1, x2), (y1, y2), 1)
slope = (y2 - y1) / (x2 - x1)
intercept = y1 - (slope * x1)
if slope < 0:
if x1 < left_region_boundary and x2 < left_region_boundary:
left_fit.append((slope, intercept))
else:
if x1 > right_region_boundary and x2 > right_region_boundary:
right_fit.append((slope, intercept))
left_fit_average = np.average(left_fit, axis=0)
if len(left_fit) > 0:
lane_lines.append(make_points(frame, left_fit_average))
right_fit_average = np.average(right_fit, axis=0)
if len(right_fit) > 0:
lane_lines.append(make_points(frame, right_fit_average))
return lane_lines
def make_points(frame, line):
height, width, _ = frame.shape
slope, intercept = line
y1 = height # bottom of the frame
y2 = int(y1 / 2) # make points from middle of the frame down
if slope == 0:
slope = 0.1
x1 = int((y1 - intercept) / slope)
x2 = int((y2 - intercept) / slope)
return [[x1, y1, x2, y2]]
def display_lines(frame, lines, line_color=(0, 255, 0), line_width=6):
line_image = np.zeros_like(frame)
if lines is not None:
for line in lines:
for x1, y1, x2, y2 in line:
cv2.line(line_image, (x1, y1), (x2, y2), line_color, line_width)
line_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)
return line_image
def display_heading_line(frame, steering_angle, line_color=(0, 0, 255), line_width=5 ):
heading_image = np.zeros_like(frame)
height, width, _ = frame.shape
steering_angle_radian = steering_angle / 180.0 * math.pi
x1 = int(width / 2)
y1 = height
x2 = int(x1 - height / 2 / math.tan(steering_angle_radian))
y2 = int(height / 2)
cv2.line(heading_image, (x1, y1), (x2, y2), line_color, line_width)
heading_image = cv2.addWeighted(frame, 0.8, heading_image, 1, 1)
return heading_image
def get_steering_angle(frame, lane_lines):
height,width,_ = frame.shape
if len(lane_lines) == 2:
_, _, left_x2, _ = lane_lines[0][0]
_, _, right_x2, _ = lane_lines[1][0]
mid = int(width / 2)
x_offset = (left_x2 + right_x2) / 2 - mid
y_offset = int(height / 2)
elif len(lane_lines) == 1:
x1, _, x2, _ = lane_lines[0][0]
x_offset = x2 - x1
y_offset = int(height / 2)
elif len(lane_lines) == 0:
x_offset = 0
y_offset = int(height / 2)
angle_to_mid_radian = math.atan(x_offset / y_offset)
angle_to_mid_deg = int(angle_to_mid_radian * 180.0 / math.pi)
steering_angle = angle_to_mid_deg + 90
return steering_angle
''' PWM INITIALIZATION '''
pwm = PWMControl()
''' CAMERA WORK '''
video = cv2.VideoCapture(2)
video.set(cv2.CAP_PROP_FRAME_WIDTH,320)
video.set(cv2.CAP_PROP_FRAME_HEIGHT,240)
time.sleep(2)
''' CONSTANTS (for PD algorithm) '''
speed = 8
lastTime = 0
lastError = 0
''' STOP SIGN DETECTION '''
def check_for_stop_sign(frame):
# Range of red in HSV
left_lower_red = np.array([0,40,100], dtype="uint8")
left_upper_red = np.array([25,130,200], dtype="uint8")
right_lower_red = np.array([150, 40, 100], dtype="uint8")
right_upper_red = np.array([200, 130, 200], dtype="uint8")
# Right orientation for HSV function
left_lower_red = np.flip(left_lower_red)
left_upper_red = np.flip(left_upper_red)
right_lower_red = np.flip(right_lower_red)
right_upper_red = np.flip(right_upper_red)
# Create mask for 'red' detection
left_mask = cv2.inRange(frame, left_lower_red, left_upper_red)
right_mask = cv2.inRange(frame, right_lower_red, right_upper_red)
mask = cv2.bitwise_or(left_mask, right_mask)
num_red_px = cv2.countNonZero(mask)
'''
Average HSV value for red construction paper:
125.98791666666666
107.065
163.78041666666667
'''
# TESTING:
# center = frame[:, :, :]
# center[:110, :, :] = 0
# center[130:, :, :] = 0
# center[:, :110, :] = 0
# center[:, 230:, :] = 0
# center = center[110:130, 110:230, :]
# print(np.mean(center[:,:,0]))
# print(np.mean(center[:,:,1]))
# print(np.mean(center[:,:,2]))
# print(np.average(center[110:130, 110:230, :], axis=1))
# cv2.imshow("center", center)
# print(frame.shape)
# Filter out non red pixels and get count of number of red pixels
# mask = cv2.inRange(frame, lower_red, upper_red, axis=2)
# num_red_px = cv2.countNonZero(mask)
# cv2.imshow("Mask", mask)
# cv2.imshow("Mask", cv2.bitwise_and(frame, frame, mask=mask))
return num_red_px
# Set up signal handler so ctrl+c triggers the handler
# This means the shutdown code will actually run
done = False
def stop(signum, stackframe):
global done
done = True
signal.signal(signal.SIGINT, stop)
pwm.set_throttle_direct(7.9)
show_camera = False
''' SETTING P AND D VALUES '''
kp = 0.2 # change for testing purposes
kd = kp * 0.1
stop_timing = 0
stop_state = 0
''' PLOTTING DATA '''
error_data = []
steering_pwm_data = []
throttle_pwm_data = []
proportional_resp_data = []
derivative_resp_data = []
''' MAIN FUNCTION '''
while not done:
# PWM control based on stop sign detection
if stop_state in {0, 2, 3}:
if not show_camera:
throttle_pwm_data.append(pwm.set_throttle(500))
elif stop_state in {1, 4}:
if not show_camera:
throttle_pwm_data.append(pwm.set_throttle(0))
ret,frame = video.read()
#frame = cv2.flip(frame,-1)
# Detect lanes
edges = detect_edges(frame)
roi = region_of_interest(edges)
line_segments = detect_line_segments(roi)
lane_lines = average_slope_intercept(frame,line_segments)
lane_lines_image = display_lines(frame,lane_lines)
steering_angle = get_steering_angle(frame, lane_lines)
heading_image = display_heading_line(lane_lines_image,steering_angle)
if show_camera:
cv2.imshow("heading line",heading_image)
# Stop sign detection (x2)
red_px = check_for_stop_sign(frame)
print(f"{red_px=}")
print(f"{stop_state=}")
if stop_state == 0 and red_px > 1800:
print(f'Stopping! {stop_state}')
if not show_camera:
pwm.set_throttle(0)
stop_state += 1
stop_timing = time.time()
elif stop_state == 1 and time.time() - stop_timing > 2:
stop_state += 1
stop_timing = time.time()
elif stop_state == 2 and red_px < 600:
stop_state += 1
stop_timing = time.time()
elif stop_state == 3 and red_px > 3600:
stop_state += 1
''' CALCULATE DERIVATIVE FROM PD ALGORITHM '''
now = time.time()
dt = now - lastTime
deviation = steering_angle - 90
error = -deviation
base_turn = 7.5
proportional = kp * error
derivative = kd * (error - lastError) / dt
error_data.append(error)
proportional_resp_data.append(proportional)
derivative_resp_data.append(derivative)
''' FOR PLOTTING PURPOSES '''
# p_vals.append(proportional)
# d_vals.append(derivative)
# err_vals.append(error)
''' DETERMINE TURN AMOUNT (WITH PWM CONTROL) '''
turn_amt = base_turn + proportional + derivative
if turn_amt < 6:
turn_amt = 6
elif turn_amt > 9:
turn_amt = 9
# print(f"Turn amt: {turn_amt}")
steering_pwm_data.append(pwm.set_steering(turn_amt))
lastError = error
# error = abs(deviation)
''' FOR TESTING PURPOSES'''
# print("Stop detected is: ",check_for_stop_sign(frame))
# if deviation < 5 and deviation > -5:
# deviation = 0
# error = 0
# #this state should never happen
# elif deviation > 5: # right turn
# pwm.set_steering(6.75)
# print("turn right")
# #put code to turn right
# elif deviation < -5: #left turn
# pwm.set_steering(8.25)
# print("turn left")
# #put code to turn left
# derivative = kd * (error - lastError) / dt
# proportional = kp * error
# PD = int(speed + derivative + proportional)
# spd = abs(PD)
# if spd > 25:
# spd = 25
lastTime = time.time()
key = cv2.waitKey(1)
if key == 27:
break
''' SHUTDOWN PROTOCOL '''
video.release()
pwm.shutdown()
with open("data.py", 'w') as data:
data.write(f"{error_data=}")
data.write("\n")
data.write(f"{throttle_pwm_data=}")
data.write("\n")
data.write(f"{steering_pwm_data=}")
data.write("\n")
data.write(f"{proportional_resp_data=}")
data.write("\n")
data.write(f"{derivative_resp_data=}")
import time
class PWMControl:
''' initialization '''
def __init__(self):
self.jumped = False
self.speed = open("/sys/module/gpiod_driver/parameters/rot_time", "r")
# self.last_rot = open("/sys/module/gpiod_driver/parameters/last_time", "r")
self.cur_throttle = 7.5
# P9_14 - Speed/ESC (7.75%)
with open('/dev/bone/pwm/1/a/period', 'w') as filetowrite:
filetowrite.write('20000000')
with open('/dev/bone/pwm/1/a/duty_cycle', 'w') as filetowrite:
filetowrite.write('1500000')
with open('/dev/bone/pwm/1/a/enable', 'w') as filetowrite:
filetowrite.write('1')
# P9_16 - Steering (7.5%)
with open('/dev/bone/pwm/1/b/period', 'w') as filetowrite:
filetowrite.write('20000000')
with open('/dev/bone/pwm/1/b/duty_cycle', 'w') as filetowrite:
filetowrite.write('1500000')
with open('/dev/bone/pwm/1/b/enable', 'w') as filetowrite:
filetowrite.write('1')
''' gets the speed of the RC car '''
def get_speed(self):
self.speed.seek(0)
cur_speed = float(self.speed.read())
with open('/dev/meschar', 'r') as reset:
reset.read()
return cur_speed
# def get_last_rot(self):
# self.last_rot.seek(0)
# return int(self.last_rot.read())
def percent_to_period(self, percent: float):
return str(int(percent * 200000))
''' set throttle value given PWM percent '''
def set_throttle_direct(self, percent):
self.cur_throttle = percent
with open('/dev/bone/pwm/1/a/duty_cycle', 'w') as throttle:
# print(self.percent_to_period(percent))
throttle.write(self.percent_to_period(percent))
''' set throttle value given rotational period for constant speed '''
def set_throttle(self, rot_period: float):
# if vehicle was previously stopped
if rot_period == 0:
print("rot_period 0")
self.jumped = False
self.set_throttle_direct(7.9)
return 7.9
# if vehicle was not previously stopped
cur_rot_period = self.get_speed()
print(cur_rot_period)
diff = abs(cur_rot_period - rot_period)
jump = 0
if cur_rot_period == 1000000 and not self.jumped:
print("Jumped")
self.jumped = True
jump = 0.05
delta = 0.001
# print(time.time_ns() / 1000000)
# print(self.get_last_rot())
# if time.time_ns() / 1000000 - self.get_last_rot() > 250:
# self.set_throttle_direct(self.cur_throttle + delta)
# print(f"Manually increasing: {self.cur_throttle}")
# return
# Speed is changed based on throttle error
if diff < 1:
pass
elif rot_period > cur_rot_period:
self.set_throttle_direct(self.cur_throttle - (jump + self.diff_to_delta(diff)))
print(f"Decreasing: {self.cur_throttle}")
return self.cur_throttle
elif rot_period < cur_rot_period:
self.set_throttle_direct(self.cur_throttle + (jump + self.diff_to_delta(diff)))
print(f"Increasing: {self.cur_throttle}")
return self.cur_throttle
''' detect throttle error '''
def diff_to_delta(self, diff):
if diff < 30:
return -0.0005
elif diff < 25:
return 0.0001
elif diff < 400:
return 0.0001
else:
return 0.0003
''' set steering '''
def set_steering(self, percent: float):
with open('/dev/bone/pwm/1/b/duty_cycle', 'w') as steering:
steering.write(self.percent_to_period(percent))
return percent
''' shutdown '''
def shutdown(self):
print("Shutting down PWM...")
# Center steering and stop motor
self.set_throttle_direct(7.5)
self.set_steering(7.5)
time.sleep(0.2)
# Shut down throttle
with open('/dev/bone/pwm/1/a/enable', 'w') as filetowrite:
filetowrite.write('1')
# Shut down steering
with open('/dev/bone/pwm/1/b/enable', 'w') as filetowrite:
filetowrite.write('0')
# Close speed file
self.speed.close()
# self.last_rot.close()
# PWM testing
if __name__ == "__main__":
pwm = PWMControl()
import signal, sys, select
time.sleep(3)
# pwm.set_steering(9)
pwm.set_throttle_direct(8)
# print("9")
# pwm.set_steering(9)
# time.sleep(3)
# print("6")
# pwm.set_steering(6)
# time.sleep(3)
# print("7.5")
# pwm.set_steering(7.5)
run = True
def stop(signum, stackframe):
global run
print("Stopping...")
run = False
signal.signal(signal.SIGINT, stop)
# start = time.time()
# while run:
# if time.time() - start > 3:
# break
target = 0
while run:
i, o, e = select.select( [sys.stdin], [], [], 0.01 )
if i:
try:
target = int(sys.stdin.readline().strip())
except ValueError:
pass
pwm.set_throttle(target)
time.sleep(0.1)
pwm.shutdown()
error_data=[-22, 6, -24, -6, 2, -25, -25, -24, 5, 8, -16, 4, -8, -15, 6, -22, -3, -22, -30, -23, -31, -35, -30, -34, -23, -37, -33, -30, -34, -42, -38, -40, -35, -39, -45, -43, -47, -46, -47, -48, -33, -49, -49, -48, -47, -45, -44, -43, -46, -45, -43, -44, -44, -43, -43, -44, -41, -42, -43, -42, -43, -41, -43, -43, 79, -44, -42, -29, -41, -17, -26, -27, -27, 82, -26, -24, -24, -21, -21, -22, -22, -20, -19, -16, -17, -9, -8, -8, -2, 12, 4, 0, 1, 3, 8, 13, 6, 10, 9, 5, 3, 0, -5, -4, -6, -11, -11, -9, -9, -7, -8, -2, -1, -2, 0, 6, 5, 9, 11, 10, 12, 11, 9, 6, 4, 0, -4, -9, -14, -19, -19, -21, -19, -14, -11, -7, -1, 3, 7, 10, 11, 13, 14, 10, 7, 4, -1, -6, -11, -13, -16, -16, -15, -14, -9, -6, -4, 0, 3, 8, 9, 12, 10, 11, 6, 4, 3, -2, -5, -9, -7, -9, -11, -6, -8, -5, -3, -3, -1, 0, 2, 2, 2, 5, 4, 2, 0, 4, 0, 1, 0, 0, 0, 1, -4, -3, 0, -2, -3, -5, 0, 4, -4, 9, -5, -3, 0, -2, 1, 0, -2, 1, 0, 0, -2, 0, 3, 4, 2, -1, 2, 0, 3, 2, 0, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, -3, 0, -2, 0, 0, -1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -2, -2, 0, 0, 0, 0, 0, 2, 0, 1, 3, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, -2, 0, -3, -2, -3, -5, -3, -2, -2, -3, -3, -3, -2, -2, -5, -2, -1, 0, 0, 0, 0, 1, 1, 0, 0, -1, 0, -2, -1, -2, -2, 0, -2, -3, -3, -2, 1, -2, -3, 0, 0, 0, -2, 0, 0, 0, -2, 0, 0, 0, 1, -1, -1, 0, 2, 0, 0, 2, -1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, -3, -4, 0, -4, 0, 0, 0, -3, -3, 5, 7, 8, 11, 11, 17, 14, 18, 17, 14, 23, 16, 21, 18, 21, 20, 21, 21, 22, 21, 19, 19, 17, 15, 11, 11, 9, 8, 5, 3, 1, 0, 0, -3, -1, -4, -1, 3, 6, 8, 5, 7, 14, 13, -25, 44, 47, 50, 46, 50, 21, 21, 14, 21, 10, 18, 15, 19, 14, 16, 20, 15, 16, 9, 41, 41, 42, 10, -31, 13, 12, -41, 50, 51, 9, 19, 15, 14, -41, 46, 48, 51, 47, 22, 51, 48, 49, 49, 52, 49, -33, 50, 20, 53, 17, 25, 45, 14, 10, 14, -34, 14, 51, -74, -42, -29, 48, -56, 56, 55, 55, 57, 54, 57, 56, 56, 54, 55, 51, 52, -20, 49, 47, 50, 51, 51, 52, 53, 50, 48, 48, 49, 45, 48, 47, 52, 45, 44, 4, 44, 40, 41, 42, 43, 44, 39, 40, 41, 42, -29, 38, 41, 40, 38, 28, 26, 28, 25, 23, 20, 16, 20, 15, 12, 10, 7, 6, 2, 1, 0, 0, -3, -1, -1, 0, -1, 2, 4, 5, 6, 6, 5, 7, 5, 4, 1, 1, -1, -3, -5, -6, -6, -4, -3, 0, 8, 9, 13, 22, 30, 30, 16, -2, -23, 48, 34, 34, 30, 32, 29, 46, 30, 32, 43, 31, -80, 30, 32, 27, 31, 31, 30, 32, 31, 26, 30, 30, 30, 25, 22, 20, 18, 16, 14, 11, 7, 5, 2, 1, -1, -3, -5, -6, -5, -3, 0, 1, 8, 9, 13, 15, 15, 16, 16, 11, 9, 8, 6, 3, 0, -1, -3, -3, -7, -7, -6, -5, -3, -3, -2, -1, 0, 0, 2, 3, 2, 0, 0, 3, -1, -2, 0, -3, -3, -8, -2, 0, -10, -5, 0, -1, -5, -13, -2, -3, -4, 4, 2, 3, -2, 0, 0, 2, 3, 0, -2, 0, 0, -4, 2, -2, -3, -9, -1, -11, -6, -2, -2, -3, -9, -1, 0, -4, 0, 0, -10, 1, -8, -18, -1, -3, 3, 0, 0, 3, -5, 0, -6, 2, -12, 2, -11, -4, -6, 1, -6, 0, -2, 3, -3, -3, -5, -21, -8]
throttle_pwm_data=[7.9003000000000005, 7.9506000000000006, 7.950900000000001, 7.951200000000001, 7.951500000000001, 7.951800000000001, 7.9521000000000015, 7.952400000000002, 7.952700000000002, 7.953000000000002, 7.953300000000002, 7.9536000000000024, 7.953900000000003, 7.954200000000003, 7.954500000000003, 7.954800000000003, 7.955100000000003, 7.955400000000004, 7.955700000000004, 7.956000000000004, 7.956300000000004, 7.956600000000004, 7.9569000000000045, 7.957200000000005, 7.957500000000005, 7.957800000000005, 7.958100000000005, 7.9584000000000055, 7.958700000000006, 7.959000000000006, 7.959300000000006, 7.959600000000006, 7.959900000000006, 7.960200000000007, 7.960500000000007, 7.960800000000007, 7.961100000000007, 7.961400000000007, 7.9617000000000075, 7.962000000000008, 7.962300000000008, 7.962600000000008, 7.962900000000008, 7.9632000000000085, 7.963500000000009, 7.963800000000009, 7.964100000000009, 7.964400000000009, 7.964700000000009, 7.96500000000001, 7.96530000000001, 7.96560000000001, 7.96590000000001, 7.96620000000001, 7.966500000000011, 7.966800000000011, 7.967100000000011, 7.967400000000011, 7.967700000000011, 7.967800000000011, 7.968100000000011, 7.968200000000011, 7.968500000000011, 7.968800000000011, 7.968900000000011, 7.969000000000011, 7.969100000000011, 7.9692000000000105, 7.969500000000011, 7.969800000000011, 7.969900000000011, 7.97000000000001, 7.97010000000001, 7.97020000000001, 7.97030000000001, 7.9704000000000095, 7.970500000000009, 7.970600000000009, 7.970700000000009, 7.9708000000000085, 7.970900000000008, 7.971000000000008, 7.971100000000008, 7.971200000000008, 7.971300000000007, 7.971400000000007, 7.971500000000007, 7.971600000000007, 7.9717000000000064, 7.971800000000006, 7.9713000000000065, 7.970800000000007, 7.9709000000000065, 7.970400000000007, 7.969900000000007, 7.970400000000007, 7.9709000000000065, 7.971400000000006, 7.9713000000000065, 7.970800000000007, 7.9713000000000065, 7.971800000000006, 7.971900000000006, 7.971800000000006, 7.971900000000006, 7.972000000000006, 7.971900000000006, 7.971800000000006, 7.9717000000000064, 7.971200000000007, 7.9717000000000064, 7.972200000000006, 7.972100000000006, 7.972600000000006, 7.973100000000006, 7.973000000000006, 7.973500000000006, 7.973400000000006, 7.973300000000006, 7.9732000000000065, 7.973100000000007, 7.973000000000007, 7.972900000000007, 7.972800000000007, 7.972700000000008, 7.972600000000008, 7.972500000000008, 7.972400000000008, 7.972300000000009, 7.972200000000009, 7.972100000000009, 7.972000000000009, 7.9719000000000095, 7.97180000000001, 7.97170000000001, 7.97160000000001, 7.9715000000000105, 7.971400000000011, 7.971300000000011, 7.971200000000011, 7.971100000000011, 7.971000000000012, 7.970900000000012, 7.970800000000012, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9003000000000005, 7.900600000000001, 7.900900000000001, 7.901200000000001, 7.901500000000001, 7.9018000000000015, 7.902100000000002, 7.902400000000002, 7.902700000000002, 7.953000000000002, 7.953300000000002, 7.9536000000000024, 7.953900000000003, 7.954200000000003, 7.954500000000003, 7.954800000000003, 7.955100000000003, 7.955400000000004, 7.955700000000004, 7.956000000000004, 7.956300000000004, 7.956600000000004, 7.9569000000000045, 7.957200000000005, 7.957500000000005, 7.957800000000005, 7.958100000000005, 7.9584000000000055, 7.958700000000006, 7.959000000000006, 7.959300000000006, 7.959600000000006, 7.959900000000006, 7.960200000000007, 7.960500000000007, 7.960800000000007, 7.961100000000007, 7.961400000000007, 7.9617000000000075, 7.962000000000008, 7.962300000000008, 7.962600000000008, 7.962900000000008, 7.9632000000000085, 7.963500000000009, 7.963800000000009, 7.964100000000009, 7.964400000000009, 7.964700000000009, 7.96500000000001, 7.96530000000001, 7.96560000000001, 7.96590000000001, 7.96620000000001, 7.966500000000011, 7.966800000000011, 7.967100000000011, 7.967400000000011, 7.967700000000011, 7.9680000000000115, 7.968100000000011, 7.968200000000011, 7.968300000000011, 7.968400000000011, 7.96850000000001, 7.9688000000000105, 7.969100000000011, 7.969400000000011, 7.969500000000011, 7.969800000000011, 7.970100000000011, 7.970200000000011, 7.970300000000011, 7.970600000000011, 7.970900000000011, 7.971000000000011, 7.9711000000000105, 7.971400000000011, 7.971700000000011, 7.971800000000011, 7.97190000000001, 7.97200000000001, 7.97230000000001, 7.972600000000011, 7.97270000000001, 7.97280000000001, 7.97290000000001, 7.97300000000001, 7.973100000000009, 7.97340000000001, 7.973500000000009, 7.9738000000000095, 7.97410000000001, 7.97440000000001, 7.97470000000001, 7.97480000000001, 7.97490000000001, 7.975000000000009, 7.975100000000009, 7.975200000000009, 7.975300000000009, 7.9754000000000085, 7.975500000000008, 7.975600000000008, 7.975700000000008, 7.9758000000000076, 7.975900000000007, 7.976000000000007, 7.976100000000007, 7.976200000000007, 7.976300000000006, 7.976400000000006, 7.976500000000006, 7.976600000000006, 7.9767000000000055, 7.976800000000005, 7.976900000000005, 7.977000000000005, 7.9775000000000045, 7.977600000000004, 7.9771000000000045, 7.977200000000004, 7.976700000000005, 7.976200000000005, 7.976700000000005, 7.977200000000004, 7.977700000000004, 7.978200000000004, 7.977700000000004, 7.978200000000004, 7.978100000000004, 7.978200000000004, 7.9783000000000035, 7.978400000000003, 7.978500000000003, 7.979000000000003, 7.9795000000000025, 7.979400000000003, 7.9795000000000025, 7.979600000000002, None, 7.979700000000002, 7.980200000000002, 7.980100000000002, 7.980200000000002, 7.9803000000000015, 7.980400000000001, 7.980900000000001, 7.981000000000001, 7.980900000000001, 7.980800000000001, 7.9807000000000015, 7.981200000000001, 7.981700000000001, 7.982200000000001, 7.9823, 7.9824, 7.9823, 7.982200000000001, 7.9823, 7.9828, 7.9827, 7.982600000000001, 7.982500000000001, 7.982600000000001, 7.982500000000001, 7.982600000000001, 7.9831, 7.9830000000000005, 7.982900000000001, 7.982800000000001, 7.982300000000001, 7.982800000000001, 7.983300000000001, 7.983200000000001, 7.983100000000001, 7.983000000000001, 7.983100000000001, 7.9826000000000015, 7.982100000000002, 7.9822000000000015, 7.982700000000001, 7.983200000000001, 7.983700000000001, 7.983200000000001, 7.983300000000001, 7.9834000000000005, 7.9835, 7.9830000000000005, 7.9835, 7.9834000000000005, 7.982900000000001, 7.982400000000001, 7.982500000000001, 7.982400000000001, 7.982300000000001, 7.982800000000001, None, 7.982300000000001, 7.982800000000001, 7.983300000000001, 7.983200000000001, 7.983100000000001, 7.983600000000001, 7.983700000000001, 7.983200000000001, 7.983300000000001, 7.983200000000001, 7.983300000000001, 7.983200000000001, 7.983700000000001, 7.983200000000001, 7.983700000000001, 7.9842, 7.9847, 7.9848, 7.9849, 7.984999999999999, 7.985099999999999, 7.985199999999999, 7.985299999999999, 7.985199999999999, 7.985099999999999, 7.985199999999999, 7.985299999999999, 7.9857999999999985, 7.985699999999999, 7.985599999999999, 7.985499999999999, 7.985399999999999, 7.985499999999999, 7.985999999999999, 7.986099999999999, 7.985999999999999, 7.985899999999999, 7.985799999999999, 7.985899999999999, 7.985399999999999, 7.985499999999999, 7.985399999999999, 7.985499999999999, 7.985399999999999, 7.9853, 7.985799999999999, 7.986299999999999, 7.986799999999999, 7.986899999999999, 7.986999999999998, 7.986899999999999, 7.986999999999998, 7.987099999999998, 7.986999999999998, 7.987099999999998, 7.987199999999998, 7.987299999999998, 7.987799999999997, 7.987899999999997, 7.988399999999997, 7.988299999999997, 7.988199999999997, 7.9880999999999975, 7.987999999999998, 7.9884999999999975, 7.988599999999997, 7.988699999999997, 7.988799999999997, 7.988699999999997, 7.988599999999997, 7.989099999999997, 7.988999999999997, 7.9888999999999974, 7.988799999999998, 7.988699999999998, 7.988599999999998, 7.989099999999998, 7.989599999999998, 7.989699999999997, 7.989799999999997, 7.989699999999997, 7.989599999999998, 7.989699999999997, 7.989799999999997, 7.990299999999997, 7.990199999999997, 7.990099999999997, 7.9899999999999975, 7.990099999999997, 7.989599999999998, 7.989699999999997, 7.989599999999998, 7.989499999999998, 7.989399999999998, 7.989499999999998, 7.989599999999998, 7.989699999999997, 7.990199999999997, 7.990299999999997, 7.990199999999997, 7.990299999999997, 7.989799999999997, 7.989299999999997, 7.989799999999997, 7.989699999999997, 7.989599999999998, 7.989699999999997, 7.990199999999997, 7.990699999999997, 7.990799999999997, 7.990299999999997, 7.990799999999997, 7.990899999999996, 7.990799999999997, 7.990899999999996, 7.990999999999996, 7.990499999999996, 7.989999999999997, 7.990499999999996, 7.990599999999996, 7.990699999999996, 7.990799999999996, 7.990299999999996, 7.990399999999996, 7.9908999999999955, 7.990999999999995, 7.991099999999995, 7.990599999999995, 7.990699999999995, 7.990799999999995, 7.990899999999995, 7.991399999999994, 7.991899999999994, 7.992399999999994, 7.9924999999999935, 7.992599999999993, 7.992699999999993, None, 7.993199999999993, 7.9932999999999925, 7.993399999999992, 7.993499999999992, 7.993599999999992, 7.993099999999992, 7.992599999999992, 7.992499999999993, 7.992599999999992, 7.992699999999992, 7.992799999999992, 7.992899999999992, 7.9929999999999914, 7.993099999999991, 7.993599999999991, 7.994099999999991, 7.99419999999999, 7.99429999999999, 7.99479999999999, 7.99469999999999, 7.99459999999999, 7.99509999999999, 7.99519999999999, 7.99469999999999, 7.99479999999999, 7.99529999999999, 7.99519999999999, 7.99509999999999, 7.99499999999999, 7.99549999999999, 7.99559999999999, 7.99549999999999, 7.99559999999999, 7.99549999999999, 7.99539999999999, 7.99589999999999, 7.99539999999999, 7.99589999999999, 7.99639999999999, 7.99629999999999, 7.99619999999999, 7.99609999999999, 7.99619999999999, 7.99629999999999, 7.99619999999999, 7.99629999999999, 7.99619999999999, 7.99609999999999, 7.99659999999999, 7.99669999999999, 7.99719999999999, 7.997299999999989, 7.99679999999999, 7.9968999999999895, 7.99639999999999, None, 7.9964999999999895, 7.996599999999989, 7.997099999999989, 7.996599999999989, 7.996699999999989, 7.996799999999989, 7.996899999999989, 7.997399999999988, 7.997499999999988, 7.997399999999988, 7.997499999999988, 7.997999999999988, 7.9984999999999875, 7.998399999999988, 7.9984999999999875, 7.998399999999988, 7.9988999999999875, 7.998999999999987, 7.999099999999987, 7.999199999999987, 7.9992999999999865, 7.999799999999986, 8.000299999999987, 8.000399999999987, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9, 7.9]
steering_pwm_data=[6, 9, 6, 9, 9, 6, 6, 6, 9, 9, 6, 9, 6, 6, 9, 6, 9, 6, 6, 7.1725838396332815, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8.496633622719425, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 9, 6, 9, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6.154341441129443, 6, 9, 6.49319501605216, 6, 9, 9, 6, 6, 8.273266452538783, 9, 9, 9, 6, 9, 8.559584804406159, 6.053646298875044, 6.858135561855555, 6, 6, 7.310826901232051, 6, 6, 6, 6.882818508047744, 6, 7.179364883296019, 6, 9, 7.828586065444647, 6.492934876214874, 8.659167858500018, 9, 7.894403037872334, 9, 9, 8.92865845269474, 9, 9, 7.880955941435689, 6.722363184861534, 7.126899367902892, 6, 6, 6, 6, 6, 6, 6, 6, 7.8867494320642475, 7.4632947365706475, 9, 9, 9, 9, 9, 9, 9, 9, 6.99847676984553, 6.863913623896634, 6.662676625396061, 6, 6, 6, 6, 6, 6, 6, 6, 8.354068454057064, 8.335197205081963, 7.772149895834665, 9, 9, 9, 9, 9, 8.278346197535898, 9, 6, 7.082875009975117, 7.487478240551433, 6, 6, 6, 7.382034478542609, 6, 6, 9, 6, 8.245142262750946, 8.137823783735927, 6.9, 8.322539585796653, 8.077831292104648, 9, 7.9, 7.9, 9, 7.743128028784239, 6.602759143276889, 6.26597285866647, 9, 6, 8.32400845043182, 6.928000054550165, 7.5, 7.5, 8.26136624016275, 6, 7.6034000234785095, 9, 6, 6.322792934748953, 6, 9, 9, 6, 9, 6, 8.019996795663465, 9, 6, 9, 6.824175179659051, 6, 9, 6.838870613084495, 7.5, 6, 8.929307888907822, 9, 8.837077149625458, 6.573538634261272, 6, 9, 6.135199791748015, 9, 7.247250996015937, 6.374609032794693, 7.5, 7.5, 7.5, 6.6424773669647825, 8.047419912685413, 6.643619533493478, 8.025938130885654, 7.5, 6.673100268288855, 8.1716904746653, 6, 9, 6, 8.633925126894976, 7.5, 6.6853824229768835, 8.102625555850892, 7.5, 7.5, 9, 6.163265901250109, 7.5, 8.262303211491925, 6.887777753450251, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 6.646651089614779, 8.024091465700362, 6.638818503542913, 7.3, 6.517247339316975, 7.1, 8.68382839401637, 7.5, 7.5, 7.5, 7.5, 9, 6.1605658810755575, 8.266036747886288, 9, 6.560491197565747, 7.7, 7.7, 7.7, 8.452190896224863, 7.045580727703926, 6.900303972662478, 8.256617011817633, 7.7, 7.7, 7.7, 6.884909224226426, 7.5, 7.5, 7.5, 6, 8.539770444051936, 6, 7.732520094705253, 6.352890703468427, 6, 8.15185354315433, 7.698024409718261, 7.1, 6.233941434288255, 6.9, 6.9, 7.794743258464188, 7.1, 6, 9, 7.841378647167778, 8.163388031727704, 7.5, 7.5, 7.5, 8.325982821792891, 7.7, 6.844286529457285, 7.5, 6.753809771851234, 8.123502898766166, 6, 7.868642082429501, 6.491481650743908, 7.1, 8.533067080454675, 6, 6.330121739130435, 6.9, 7.705059686528516, 9, 6, 6.244240396491612, 9, 7.5, 7.5, 6.036825282155599, 8.787178708157832, 7.5, 7.5, 6, 8.892392523984995, 7.5, 7.5, 8.364791732707792, 6.065727738214348, 7.3, 8.089414633118093, 9, 6.324886286430718, 7.5, 9, 6, 8.9298839553415, 6.8920990195154825, 7.5, 7.5, 7.5, 7.5, 8.208656354408582, 6.767754189944134, 7.5, 7.5, 6, 6.175531714026697, 9, 6, 9, 7.5, 7.5, 6, 6.9, 9, 9, 9, 9, 9, 9, 8.325265107227771, 9, 9, 8.387252772309587, 9, 6.8649823663105085, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6.954093193014614, 9, 7.879574309565336, 8.489213126451679, 6.854346697357493, 6.9470376733510175, 6.335011024237049, 6.953724407397759, 7.5, 6, 8.392266666666666, 6, 8.94967708947886, 9, 9, 9, 6.647828544512482, 9, 9, 9, 6, 9, 9, 9, 9, 9, 6, 9, 6.435503198462632, 9, 6, 9, 8.53453420805998, 9, 7.3835217711766585, 9, 9, 7.78455467723244, 9, 6, 9, 9, 9, 6, 6, 9, 9, 6, 9, 9, 6, 9, 8.351375002401275, 9, 6, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 6, 9, 6, 9, 6, 9, 9, 6, 7.047674654856132, 9, 6, 9, 9, 6, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 7.385300088561891, 9, 9, 9, 9, 9, 9, 9, 7.724906544220297, 7.902553853480435, 7.8678004455729695, 7.239634751398713, 8.003364336965186, 6, 7.203585664915021, 6.847159556088222, 7.5, 6, 8.615117423886119, 7.3, 8.063515739409654, 6.624876823899624, 9, 9, 9, 9, 8.7, 7.825495670073251, 9, 7.275894992594322, 7.71711776313961, 6, 7.7, 6.122387062357863, 6, 6, 6, 6.3, 7.641313344405045, 7.471088720657916, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 9, 6, 9, 9, 9, 9, 9, 6, 9, 9, 6.271522692052245, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7.399208806077948, 6, 6.911158209746766, 6, 7.103387670336548, 6.0878172031357245, 6, 6, 6, 7.070389751679495, 8.061736384724579, 9, 8.305999450970194, 9, 9, 9, 9, 9, 9, 9, 6.51837531954274, 8.048575989258943, 8.513457886419891, 7.472850779347118, 6.207206594662895, 6, 6.713494794689114, 6, 6.9, 6, 6.1, 6.861137176991565, 7.081750395295293, 8.212011511331468, 6.9, 7.733690746882011, 7.914383500443103, 8.049478138407625, 7.5, 9, 8.697636699130113, 7.274371993466733, 6.246406641112431, 7.5, 9, 6, 6.489244255467862, 8.760800192382842, 6, 6.9, 6, 9, 8.548739865604, 6, 9, 9, 6.620749485821633, 6, 6, 9, 6.2770157145827765, 6.15935408194175, 9, 6.642686361354047, 8.652176357137686, 6, 8.789364893944052, 7.5, 9, 8.738591971741993, 6, 6, 8.791926506599314, 7.5, 6, 9, 6, 6.262785673591857, 6, 9, 6, 9, 9, 7.1, 6.28529234602279, 6, 9, 8.14396484090124, 6, 9, 7.5, 6, 9, 6, 6, 9, 6, 9, 6, 7.5, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 6.9, 6, 6, 9]
proportional_resp_data=[-4.4, 1.2000000000000002, -4.800000000000001, -1.2000000000000002, 0.4, -5.0, -5.0, -4.800000000000001, 1.0, 1.6, -3.2, 0.8, -1.6, -3.0, 1.2000000000000002, -4.4, -0.6000000000000001, -4.4, -6.0, -4.6000000000000005, -6.2, -7.0, -6.0, -6.800000000000001, -4.6000000000000005, -7.4, -6.6000000000000005, -6.0, -6.800000000000001, -8.4, -7.6000000000000005, -8.0, -7.0, -7.800000000000001, -9.0, -8.6, -9.4, -9.200000000000001, -9.4, -9.600000000000001, -6.6000000000000005, -9.8, -9.8, -9.600000000000001, -9.4, -9.0, -8.8, -8.6, -9.200000000000001, -9.0, -8.6, -8.8, -8.8, -8.6, -8.6, -8.8, -8.200000000000001, -8.4, -8.6, -8.4, -8.6, -8.200000000000001, -8.6, -8.6, 15.8, -8.8, -8.4, -5.800000000000001, -8.200000000000001, -3.4000000000000004, -5.2, -5.4, -5.4, 16.400000000000002, -5.2, -4.800000000000001, -4.800000000000001, -4.2, -4.2, -4.4, -4.4, -4.0, -3.8000000000000003, -3.2, -3.4000000000000004, -1.8, -1.6, -1.6, -0.4, 2.4000000000000004, 0.8, 0.0, 0.2, 0.6000000000000001, 1.6, 2.6, 1.2000000000000002, 2.0, 1.8, 1.0, 0.6000000000000001, 0.0, -1.0, -0.8, -1.2000000000000002, -2.2, -2.2, -1.8, -1.8, -1.4000000000000001, -1.6, -0.4, -0.2, -0.4, 0.0, 1.2000000000000002, 1.0, 1.8, 2.2, 2.0, 2.4000000000000004, 2.2, 1.8, 1.2000000000000002, 0.8, 0.0, -0.8, -1.8, -2.8000000000000003, -3.8000000000000003, -3.8000000000000003, -4.2, -3.8000000000000003, -2.8000000000000003, -2.2, -1.4000000000000001, -0.2, 0.6000000000000001, 1.4000000000000001, 2.0, 2.2, 2.6, 2.8000000000000003, 2.0, 1.4000000000000001, 0.8, -0.2, -1.2000000000000002, -2.2, -2.6, -3.2, -3.2, -3.0, -2.8000000000000003, -1.8, -1.2000000000000002, -0.8, 0.0, 0.6000000000000001, 1.6, 1.8, 2.4000000000000004, 2.0, 2.2, 1.2000000000000002, 0.8, 0.6000000000000001, -0.4, -1.0, -1.8, -1.4000000000000001, -1.8, -2.2, -1.2000000000000002, -1.6, -1.0, -0.6000000000000001, -0.6000000000000001, -0.2, 0.0, 0.4, 0.4, 0.4, 1.0, 0.8, 0.4, 0.0, 0.8, 0.0, 0.2, 0.0, 0.0, 0.0, 0.2, -0.8, -0.6000000000000001, 0.0, -0.4, -0.6000000000000001, -1.0, 0.0, 0.8, -0.8, 1.8, -1.0, -0.6000000000000001, 0.0, -0.4, 0.2, 0.0, -0.4, 0.2, 0.0, 0.0, -0.4, 0.0, 0.6000000000000001, 0.8, 0.4, -0.2, 0.4, 0.0, 0.6000000000000001, 0.4, 0.0, 0.0, 0.0, 0.0, -0.2, 0.0, -0.2, 0.0, 0.0, -0.2, 0.0, -0.6000000000000001, 0.0, -0.4, 0.0, 0.0, -0.2, 0.0, 0.0, 0.0, 0.4, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.2, 0.0, -0.2, -0.2, -0.4, -0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.0, 0.2, 0.6000000000000001, 0.2, 0.2, 0.2, 0.2, 0.4, 0.2, 0.0, 0.2, 0.2, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, -0.4, 0.0, -0.6000000000000001, -0.4, -0.6000000000000001, -1.0, -0.6000000000000001, -0.4, -0.4, -0.6000000000000001, -0.6000000000000001, -0.6000000000000001, -0.4, -0.4, -1.0, -0.4, -0.2, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.0, 0.0, -0.2, 0.0, -0.4, -0.2, -0.4, -0.4, 0.0, -0.4, -0.6000000000000001, -0.6000000000000001, -0.4, 0.2, -0.4, -0.6000000000000001, 0.0, 0.0, 0.0, -0.4, 0.0, 0.0, 0.0, -0.4, 0.0, 0.0, 0.0, 0.2, -0.2, -0.2, 0.0, 0.4, 0.0, 0.0, 0.4, -0.2, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, -0.6000000000000001, -0.8, 0.0, -0.8, 0.0, 0.0, 0.0, -0.6000000000000001, -0.6000000000000001, 1.0, 1.4000000000000001, 1.6, 2.2, 2.2, 3.4000000000000004, 2.8000000000000003, 3.6, 3.4000000000000004, 2.8000000000000003, 4.6000000000000005, 3.2, 4.2, 3.6, 4.2, 4.0, 4.2, 4.2, 4.4, 4.2, 3.8000000000000003, 3.8000000000000003, 3.4000000000000004, 3.0, 2.2, 2.2, 1.8, 1.6, 1.0, 0.6000000000000001, 0.2, 0.0, 0.0, -0.6000000000000001, -0.2, -0.8, -0.2, 0.6000000000000001, 1.2000000000000002, 1.6, 1.0, 1.4000000000000001, 2.8000000000000003, 2.6, -5.0, 8.8, 9.4, 10.0, 9.200000000000001, 10.0, 4.2, 4.2, 2.8000000000000003, 4.2, 2.0, 3.6, 3.0, 3.8000000000000003, 2.8000000000000003, 3.2, 4.0, 3.0, 3.2, 1.8, 8.200000000000001, 8.200000000000001, 8.4, 2.0, -6.2, 2.6, 2.4000000000000004, -8.200000000000001, 10.0, 10.200000000000001, 1.8, 3.8000000000000003, 3.0, 2.8000000000000003, -8.200000000000001, 9.200000000000001, 9.600000000000001, 10.200000000000001, 9.4, 4.4, 10.200000000000001, 9.600000000000001, 9.8, 9.8, 10.4, 9.8, -6.6000000000000005, 10.0, 4.0, 10.600000000000001, 3.4000000000000004, 5.0, 9.0, 2.8000000000000003, 2.0, 2.8000000000000003, -6.800000000000001, 2.8000000000000003, 10.200000000000001, -14.8, -8.4, -5.800000000000001, 9.600000000000001, -11.200000000000001, 11.200000000000001, 11.0, 11.0, 11.4, 10.8, 11.4, 11.200000000000001, 11.200000000000001, 10.8, 11.0, 10.200000000000001, 10.4, -4.0, 9.8, 9.4, 10.0, 10.200000000000001, 10.200000000000001, 10.4, 10.600000000000001, 10.0, 9.600000000000001, 9.600000000000001, 9.8, 9.0, 9.600000000000001, 9.4, 10.4, 9.0, 8.8, 0.8, 8.8, 8.0, 8.200000000000001, 8.4, 8.6, 8.8, 7.800000000000001, 8.0, 8.200000000000001, 8.4, -5.800000000000001, 7.6000000000000005, 8.200000000000001, 8.0, 7.6000000000000005, 5.6000000000000005, 5.2, 5.6000000000000005, 5.0, 4.6000000000000005, 4.0, 3.2, 4.0, 3.0, 2.4000000000000004, 2.0, 1.4000000000000001, 1.2000000000000002, 0.4, 0.2, 0.0, 0.0, -0.6000000000000001, -0.2, -0.2, 0.0, -0.2, 0.4, 0.8, 1.0, 1.2000000000000002, 1.2000000000000002, 1.0, 1.4000000000000001, 1.0, 0.8, 0.2, 0.2, -0.2, -0.6000000000000001, -1.0, -1.2000000000000002, -1.2000000000000002, -0.8, -0.6000000000000001, 0.0, 1.6, 1.8, 2.6, 4.4, 6.0, 6.0, 3.2, -0.4, -4.6000000000000005, 9.600000000000001, 6.800000000000001, 6.800000000000001, 6.0, 6.4, 5.800000000000001, 9.200000000000001, 6.0, 6.4, 8.6, 6.2, -16.0, 6.0, 6.4, 5.4, 6.2, 6.2, 6.0, 6.4, 6.2, 5.2, 6.0, 6.0, 6.0, 5.0, 4.4, 4.0, 3.6, 3.2, 2.8000000000000003, 2.2, 1.4000000000000001, 1.0, 0.4, 0.2, -0.2, -0.6000000000000001, -1.0, -1.2000000000000002, -1.0, -0.6000000000000001, 0.0, 0.2, 1.6, 1.8, 2.6, 3.0, 3.0, 3.2, 3.2, 2.2, 1.8, 1.6, 1.2000000000000002, 0.6000000000000001, 0.0, -0.2, -0.6000000000000001, -0.6000000000000001, -1.4000000000000001, -1.4000000000000001, -1.2000000000000002, -1.0, -0.6000000000000001, -0.6000000000000001, -0.4, -0.2, 0.0, 0.0, 0.4, 0.6000000000000001, 0.4, 0.0, 0.0, 0.6000000000000001, -0.2, -0.4, 0.0, -0.6000000000000001, -0.6000000000000001, -1.6, -0.4, 0.0, -2.0, -1.0, 0.0, -0.2, -1.0, -2.6, -0.4, -0.6000000000000001, -0.8, 0.8, 0.4, 0.6000000000000001, -0.4, 0.0, 0.0, 0.4, 0.6000000000000001, 0.0, -0.4, 0.0, 0.0, -0.8, 0.4, -0.4, -0.6000000000000001, -1.8, -0.2, -2.2, -1.2000000000000002, -0.4, -0.4, -0.6000000000000001, -1.8, -0.2, 0.0, -0.8, 0.0, 0.0, -2.0, 0.2, -1.6, -3.6, -0.2, -0.6000000000000001, 0.6000000000000001, 0.0, 0.0, 0.6000000000000001, -1.0, 0.0, -1.2000000000000002, 0.4, -2.4000000000000004, 0.4, -2.2, -0.8, -1.2000000000000002, 0.2, -1.2000000000000002, 0.0, -0.4, 0.6000000000000001, -0.6000000000000001, -0.6000000000000001, -1.0, -4.2, -1.6]
derivative_resp_data=[-2.633894295649648e-10, 23.273059331774405, -18.52375954128238, 12.935734148911566, 4.304002257539027, -15.48867312676519, 0.0, 0.578185753179171, 17.26871948492614, 1.93229502910057, -13.778356670636065, 12.48787923899128, -7.390301446296162, -3.85366733388023, 13.118131776480404, -17.997304706955077, 11.481972163789877, -11.320015341127007, -4.664354305096055, 4.272583839633282, -5.004389560029829, -2.869248963187824, 2.634646163896532, -2.4572460509838674, 7.158570375714697, -7.940534956051387, 2.4109698650610034, 2.0903583354099182, -2.234206611845391, -4.969591303253135, 2.5903957262185995, -1.1413460321779654, 3.0833442377105227, -2.42072763737889, -3.250495534186241, 1.244868406407907, -2.6790607359856926, 0.5570753670733085, -0.6786021227025629, -0.6318483312368658, 7.596633622719425, -11.319512869817498, 0.0, 0.6008816303141006, 0.6108135580878874, 1.1368911235947445, 0.6190671862085253, 0.6811699553390176, -1.5267930206032958, 0.6074915632287127, 1.103865882383904, -0.8384834824329054, 0.0, 0.6817900160925894, 0.0, -0.5521182084444006, 1.971053831152048, -0.592985353164056, -0.5447077310684277, 0.6300828482367523, -0.7078217579506048, 1.061647535278112, -1.2843408431512147, 0.0, 67.55227268826859, -78.06071947888849, 1.0913997996383082, 7.46716040591063, -6.900275974582372, 17.298328135068957, -4.8684489440593275, -0.5899825578124122, 0.0, 44.62134406949224, -56.4632424448281, 1.1464780609141914, 0.0, 2.015071423995901, 0.0, -0.6957170226000416, 0.0, 0.9983466825349601, 0.6395754770926891, 1.8543414411294425, -0.6895520866727497, 5.4331242410013125, 0.5931950160521591, 0.0, 3.8476029140834633, 8.813216164496643, -4.617529432001928, -2.362755221316209, 0.5732664525387823, 1.3321594410036528, 2.8149502352333213, 3.3537529085340996, -4.538448030668398, 1.9002504261548658, -0.7404151955938428, -2.4463537011249556, -1.2418644381444446, -1.790473696942101, -2.836672528067091, 0.610826901232051, -1.3342889636469197, -3.087361432125665, 0.0, 1.1828185080477438, 0.0, 1.0793648832960192, -0.8089225754814323, 3.3321845518282394, 0.5285860654446469, -0.6070651237851257, 1.1591678585000176, 3.737766918912497, -0.6055969621276658, 2.3211261681919746, 1.162638060192789, -0.5713415473052589, 1.5210944993970827, -0.49457049536005293, -1.4190440585643118, -1.9776368151384658, -1.1731006320971082, -1.8940292054030563, -2.4801673429866, -2.4256309421915847, -3.040496418940471, -3.156982643122733, 0.0, -1.1373998169553576, 1.217372274425861, 3.1867494320642478, 2.163294736570648, 2.9190458460200093, 4.59058636823816, 2.5156830433120163, 2.611199203125244, 1.934359526206966, 0.6536441840169556, 1.423354005650245, 0.5517913501068904, -2.5015232301544708, -2.0360863761033667, -1.637323374603939, -3.084863640375394, -3.1045691741733967, -2.9858647986787408, -1.292683032068174, -1.84056228013077, 0.0, 0.6543988516865854, 0.6013554607692033, 2.6540684540570645, 2.0351972050819636, 1.072149895834665, 2.7100457941283373, 1.6418311706104558, 3.6233696450322666, 0.607060730620043, 1.7534837896027706, -1.221653802464102, 0.5719180501107892, -2.9366529903518974, -1.2171249900248837, -0.612521759448566, -3.1318772727612143, -1.8828520552454777, -2.0935275803764735, 1.2820344785426094, -1.5210531278331825, -1.0536731438332938, 2.9742618068359103, -1.240991774661223, 1.7451422627509452, 1.2378237837359267, 0.0, 1.0225395857966528, 0.5778312921046469, 1.2978128456831668, 0.0, 0.0, 1.8734468357540073, -0.5568719712157624, -1.2972408567231117, -1.2340271413335298, 2.16386671567774, -2.602187875638829, 0.6240084504318202, -0.5719999454498345, 0.0, 0.0, 0.5613662401627497, -3.108526706638307, 0.7034000234785089, 1.7645615560448193, -1.253574625471663, -0.5772070652510477, -0.9337223189986701, 3.2598386520137415, 3.8398828160761704, -4.436216427036855, 8.304919960399058, -9.103492240670978, 1.1199967956634649, 1.9041504808456229, -1.2726402184631724, 1.6823086950418142, -0.6758248203409495, -1.1554874789939118, 1.7788554625650308, -0.6611293869155049, 0.0, -1.125240008316622, 1.429307888907821, 1.8249857863897434, 0.5370771496254563, -1.3264613657387279, -1.9401606661013033, 1.5896848528492111, -1.3648002082519852, 1.540164384903028, -0.6527490039840639, -1.1253909672053075, 0.0, 0.0, 0.0, -0.6575226330352175, 0.5474199126854131, -0.6563804665065219, 0.5259381308856539, 0.0, -0.626899731711145, 0.6716904746653002, -1.673092710168534, 1.888943232227702, -1.2818189875158537, 1.1339251268949764, 0.0, -0.6146175770231163, 0.602625555850892, 0.0, 0.0, 1.1493763016551575, -1.3367340987498908, 0.0, 0.5623032114919261, -0.6122222465497487, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.6533489103852206, 0.5240914657003625, -0.6611814964570871, 0.0, -0.5827526606830246, 0.0, 1.1838283940163705, 0.0, 0.0, 0.0, 0.0, 1.3554498448810757, -1.339434118924443, 0.5660367478862881, 1.3001260045101248, -1.1395088024342537, 0.0, 0.0, 0.0, 0.5521908962248627, -0.6544192722960746, -0.5996960273375227, 0.556617011817633, 0.0, 0.0, 0.0, -0.615090775773574, 0.0, 0.0, 0.0, -1.3669352105331771, 1.0397704440519353, -1.9738055984752825, 0.6325200947052526, -0.5471092965315734, -1.2481097447571439, 1.2518535431543292, 0.5980244097182618, 0.0, -0.666058565711745, 0.0, 0.0, 0.6947432584641888, 0.0, -1.830494686538504, 1.9426918118587941, 0.5413786471677778, 0.6633880317277049, 0.0, 0.0, 0.0, 0.6259828217928916, 0.0, -0.6557134705427146, 0.0, -0.5461902281487656, 0.6235028987661663, -1.274535150493034, 0.5686420824295012, -0.6085183492560917, 0.0, 1.0330670804546744, -1.2515360342551083, -0.5698782608695653, 0.0, 0.6050596865285162, 2.1007232294901335, -1.6549277287493591, -0.655759603508388, 1.8573386275407033, 0.0, 0.0, -1.063174717844401, 1.2871787081578323, 0.0, 0.0, -1.1484872091510876, 1.392392523984995, 0.0, 0.0, 0.6647917327077919, -1.2342722617856514, 0.0, 0.5894146331180923, 1.2560428832390025, -1.1751137135692824, 0.0, 1.2856202729522834, -1.7146435920147172, 1.2298839553415, -0.6079009804845175, 0.0, 0.0, 0.0, 0.0, 0.5086563544085814, -0.7322458100558661, 0.0, 0.0, -1.9753394034536895, -0.5244682859733034, 2.561191960980376, -2.3665045948557366, 2.130575401612801, 0.0, 0.0, -1.763152201328364, 0.0, 5.736977157707565, 0.9681304134568224, 0.667866850314085, 2.0990411370233213, 0.0, 3.535245801462377, -1.9747348927722286, 2.2608365674859856, -0.6846501909829912, -1.9127472276904138, 3.9465897186588474, -3.835017633689491, 2.5761480962822385, -1.7122170664997487, 1.8264825123563868, -0.669636867271755, 0.7253506731575717, 0.0, 0.5463609837432265, -0.566327174037793, -1.6031586893579615, 0.0, -1.1734288272157567, -1.239707977418497, -2.745906806985385, 0.0, -1.420425690434665, -0.6107868735483214, -1.6456533026425066, -1.1529623266489823, -1.3649889757629508, -0.5462755926022402, 0.0, -2.0216923336466395, 1.092266666666667, -1.9335272559640433, 1.6496770894788597, 2.550465331934754, 1.8136746519069449, 1.2277778509590407, -1.852171455487518, 1.2535933588875692, 4.04133930722166, -0.5600806543148057, -18.689221749275926, 50.517464412578455, 2.163034423481886, 1.7613875065616802, -2.696629618021233, 2.0469255639739887, -20.52977585741291, 0.0, -3.8644968015373684, 4.596425574550692, -7.099363574813813, 4.019457594633446, -1.9654657919400191, 2.3827549672636383, -2.9164782288233417, 1.3098092732397009, 2.5778580867213674, -2.71544532276756, 0.5959553563182461, -4.256725843983559, 17.954828301205307, 0.0, 0.6649656364198462, -17.325682124762, -26.69312657648219, 27.963085874464944, -0.5388262045310022, -26.050356481589994, 71.09850587238165, 0.629099990250707, -25.534616822971785, 6.774293789873215, -2.148624997598725, -0.6538887503117986, -32.65112381815094, 52.77112995943514, 1.3332074602077226, 1.8829224933222601, -2.2410258602265447, -17.439063331559343, 17.518805144676012, -1.7909961355888782, 0.5962052594171998, 0.0, 1.7057990524025461, -1.5699497807195397, -55.54248100448142, 47.138497535611776, -16.26245508827255, 21.771969767277252, -23.048088776273417, 5.411001507784848, 11.91436707737102, -16.717357076275274, -2.4523253451438682, 2.598882511947085, -24.681299244212067, 34.622537274931645, 22.642968885646546, -66.35465050055055, 22.244311710696415, 7.906265016566256, 50.35453642564803, -60.31131487984958, 68.99235529968131, -0.6326966097220652, 0.0, 1.2832896830253337, -1.6970796215498118, 2.017882835928605, -0.6309975778911106, 0.0, -1.2079585856331316, 0.6596892104435358, -2.260196958062213, 0.591743004070231, -42.06661066883973, 43.215066075348304, -1.143945288795249, 1.997002333000048, 0.5773262400121129, 0.0, 0.5739528582669086, 0.5695145762895978, -2.0120265116688123, -1.2134716255117246, 0.0, 0.6250779055297652, -2.3703830965618096, 1.7319310416021476, -0.6374225315724686, 2.769468068247848, -3.586451675950357, -0.4974269449715371, -34.102805106106196, 25.68662022506316, -2.3751146345779515, 0.6842480994485955, 0.5606421386800335, 0.6222818313996619, 0.5691088813356944, -2.9299653515144746, 0.6255207075000374, 0.6288453263566648, 0.5549636137500332, -45.23122246102206, 44.49837583626936, 1.6691311384076621, -0.6422638389097314, -1.1439920902799088, -5.71469991143811, -1.2280384722364552, 1.1632345783441613, -1.572451231551718, -1.143750323820951, -1.761227254912939, -1.670413540759179, 1.6981761315039656, -2.775093455779703, -1.9974461465195654, -1.6321995544270305, -1.660365248601288, -0.6966356630348128, -2.5335189743434867, -0.49641433508497856, -0.6528404439117781, 0.0, -1.5847695814808753, 1.3151174238861194, 0.0, 0.5635157394096547, -0.675123176100376, 2.0432278126446213, 1.0278834218636084, 0.6339828894464767, 0.6148653521952651, 0.0, -0.6745043299267491, 1.1215616225900475, -1.224105007405678, -0.5828822368603909, -1.789213454387749, 0.0, -1.1776129376421374, -1.2731520675079873, -1.1908954492862671, -0.652632201345937, 0.0, 0.9413133444050453, 0.5710887206579164, 1.6179543657299365, 4.058570193104367, 0.585784376025642, 1.9913136780135787, 5.230059091255465, 5.081464116426636, 0.0, -10.423683243540701, -13.666803399618045, -16.36330237051349, 55.53142271078666, -10.478088542317233, 0.0, -2.356681556398371, 1.3567213326863985, -1.7984323814424152, 11.008247018410593, -9.320416655092917, 1.409518432637699, 6.318453026568064, -7.428477307947754, -71.91568228860949, 53.86447180241554, 1.3147773206379063, -2.6162565417267043, 2.3150886585988495, 0.0, -0.5517223961484834, 1.260534952214943, -0.6446725380796484, -2.7289788216923134, 2.3077325997248974, 0.0, 0.0, -2.161856360881174, -1.4612517637221945, -0.9983288605380447, -1.1271753458342013, -1.1797576805968681, -1.1095968942004355, -2.300791193922051, -3.203807014026143, -1.5888417902532344, -3.9623730948482185, -0.5966123296634521, -1.2121827968642753, -1.3578523272659584, -1.1224770850895858, -0.6664289686511911, 0.5703897516794953, 1.1617363847245787, 1.8594657859153685, 0.6059994509701936, 4.154450945572119, 0.5931782375652322, 2.6942045719149217, 1.1727890167349395, 0.0, 0.6180591637502304, 0.0, -3.1816246804572597, -1.2514240107410586, -0.5865421135801089, -1.2271492206528818, -1.8927934053371043, -1.6555591810957322, -0.5865052053108855, -1.3400439300633393, 0.0, -2.4107446816153812, 0.0, 0.561137176991565, 0.5817503952952926, 1.3120115113314672, 0.0, 0.6336907468820113, 0.6143835004431034, 0.5494781384076246, 0.0, 1.1713397239424428, 0.5976366991301127, -0.6256280065332668, -1.2535933588875692, 0.0, 1.5565975555445597, -3.257111018355838, -0.6107557445321374, 1.260800192382842, -1.6434287206948348, 0.0, -3.071062786015011, 4.290848081841433, 1.0487398656040008, -6.95803583278036, 3.1058565663297424, 2.667182174289058, -0.6792505141783673, -2.561524344626472, -4.552469541149975, 7.04709699098824, -0.6229842854172237, -0.54064591805825, 5.327115006032896, -1.257313638645953, 0.5521763571376853, -3.1541337664876905, 1.2893648939440518, 0.0, 1.2786927427099373, 0.6385919717419936, -1.7238164519244603, -1.2418828231984902, 1.2919265065993133, 0.0, -2.9330540816950905, 4.026853988319067, -2.279513043478261, -0.6372143264081432, -3.891662388272045, 4.2696635618669525, -6.588912452676062, 2.9744305449181634, 2.325695155846047, 0.0, -0.6147076539772104, -3.46992768060889, 5.022066034064718, 0.64396484090124, -2.2315765951503708, 2.546903283591153, 0.0, -5.733213045736626, 6.9499128574764075, -5.648936542735076, -5.593785133666305, 10.94488169154611, -1.2443975018913829, 3.2913926980950707, -1.9367712045067997, 0.0, 1.6706048234520945, -5.135908652595167, 3.096341355381663, -3.5057706452691413, 4.9713952144603315, -8.212795513192585, 8.532378579057113, -8.166846701115857, 4.4638232722905125, -1.1427998474197594, 4.517255502304006, -4.257281354899985, 3.464815888204317, -1.242112682312875, 3.1684058649785847, -3.3559354038592333, 0.0, -1.239433223504381, -9.033242788493897, 8.203091921167445]
import matplotlib.pyplot as plt
import numpy as np
from data import error_data, throttle_pwm_data, steering_pwm_data, proportional_resp_data, derivative_resp_data
# Plots relevant values throughout the run of the RC car
frames = np.arange(len(error_data))
plt.plot(frames, error_data, throttle_pwm_data, steering_pwm_data)
plt.show()
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022 BeagleBoard.org - https://beagleboard.org/
*
* https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec#PWM
*/
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/board/k3-j721e-bone-pins.h>
/*
* Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
*/
&{/chosen} {
overlays {
BONE-PWM0.kernel = __TIMESTAMP__;
};
};
&bone_pwm_0 {
status = "okay";
};
&{/} {
gpio-leds {
compatible = "gpiod_driver";
userbutton-gpios = <gpio_P8_03 GPIO_ACTIVE_HIGH>;
};
};
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/kernel.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
/* From hello.c */
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/mutex.h>
#include <linux/timekeeping.h>
#define DEVICE_NAME "meschar"
#define CLASS_NAME "mes"
static DEFINE_MUTEX(meschar_mutex);
static int majorNumber;
static struct class* mescharClass = NULL;
static struct device* mescharDevice = NULL;
static char *test_str = "Hello there";
// static char long_test_str[4096];
static ulong rot_times[3];
static ulong last_time, new_time, rot_time;
static int device_open(struct inode *, struct file *);
static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
// static ssize_t device_write(struct file *, const char __user *, size_t, loff_t *);
static int device_release(struct inode *, struct file *);
// long speed;
// module_param(speed,long,S_IRUGO);
module_param(rot_time,ulong,S_IRUGO);
// module_param(last_time,long,S_IRUGO);
static struct file_operations fops =
{
.open = device_open,
.read = device_read,
// .write = device_write,
.release = device_release,
};
/* End from hello.c*/
// Variable declaration
struct gpio_desc *gpio_button;
unsigned int irq_number;
long error_count;
// Interrupt service routine
static irq_handler_t irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs) {
printk("Interrupt Has Occurred\n");
new_time = ktime_get_ns() / 10000;
// Check if it's been longer than 1 ms since the last rotation
if (new_time - last_time > 1) {
rot_times[2] = rot_times[1];
rot_times[1] = rot_times[0];
rot_times[0] = new_time - last_time;
rot_time = (rot_times[0] + rot_times[1] + rot_times[2]) / 3;
last_time = new_time;
}
return (irq_handler_t) IRQ_HANDLED;
}
// Probe function
static int led_probe(struct platform_device *pdev) // edited
{
printk("LED Probe start\n");
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
mescharClass = class_create(THIS_MODULE, CLASS_NAME);
mescharDevice = device_create(mescharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
mutex_init(&meschar_mutex);
// Gets GPIOs for button and LED
printk("Getting gpiod...\n");
gpio_button = devm_gpiod_get(&pdev->dev, "userbutton", GPIOD_IN);
printk("Gpiod to irq...\n");
// gpio_led = devm_gpiod_get(&pdev->dev, "led", GPIOD_OUT_LOW);
irq_number = gpiod_to_irq(gpio_button); // descriptor instead of index
printk("irq_number: %u\n", irq_number);
printk("Requesting irq...\n");
// Requests IRQ
if(request_irq(irq_number, (irq_handler_t) irq_handler, IRQF_TRIGGER_RISING, "userbutton", pdev) != 0) { // null?
printk("asdsadasd \n");
return -1;
};
// Debounce function set for 1000000 ms
gpiod_set_debounce(gpio_button, 1000000);
printk("LED Probe finished\n");
// printk(KERN_INFO "Oh hi mark - I love Lisa X more than you do\n");
return 0;
}
// Remove function
static int led_remove(struct platform_device *pdev)
{
printk("Starting remove...\n");
printk("irq_number: %u\n", irq_number);
free_irq(irq_number, pdev);
printk("LED removed \n");
device_destroy(mescharClass, MKDEV(majorNumber,0));
class_unregister(mescharClass);
class_destroy(mescharClass);
unregister_chrdev(majorNumber, DEVICE_NAME);
mutex_destroy(&meschar_mutex);
// printk(KERN_INFO "sad, but still love Lisa X more than you\n");
printk("LED Remove finished\n");
return 0;
}
/* From hello.c */
// static int __init hello_init(void){
// majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
// mescharClass = class_create(THIS_MODULE, CLASS_NAME);
// mescharDevice = device_create(mescharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
// printk(KERN_INFO "Oh hi mark - I love Lisa X more than you do\n");
// mutex_init(&meschar_mutex);
// return 0;
// }
// static void __exit hello_exit(void){
// device_destroy(mescharClass, MKDEV(majorNumber,0));
// class_unregister(mescharClass);
// class_destroy(mescharClass);
// unregister_chrdev(majorNumber, DEVICE_NAME);
// mutex_destroy(&meschar_mutex);
// printk(KERN_INFO "sad, but still love Lisa X more than you\n");
// }
static int device_open(struct inode *inodep, struct file *filep){
printk("Opening device...\n");
if(!mutex_trylock(&meschar_mutex)){
printk(KERN_ALERT "I'm being used!\n");
return -EBUSY;
}
printk("Device opened\n");
// printk(KERN_INFO "You're tearing me apart, Lisa! Also I've been opened some times.\n");
return 0;
}
static ssize_t device_read(struct file *filep, char __user *buf, size_t length, loff_t *offset){
printk("Reading device...\n");
rot_time = 1000000;
// long error_count;
// error_count = copy_to_user(buf, &rot_time, sizeof(rot_time));
// memset(long_test_str, 0, 4096);
// memset(long_test_str, 80, 4095);
error_count = copy_to_user(buf, test_str, strlen(test_str));
// error_count = copy_to_user(buf, test_str, strlen(test_str));
// printk("Strlen: %lu\n", strlen(test_str));
// printk("Buffer: %s", buf);
// printk("Error count: %ld\n", error_count);
// printk("User buf length %lu\n", length);
// printk("Sent %ld characters back\n", sizeof(rot_time));
// printk("Rotation time: %ld\n", rot_time);
return 0;
}
static int device_release(struct inode *inodep, struct file *filep) {
printk("Releasing device...\n");
mutex_unlock(&meschar_mutex);
//being_used--;
// printk("I'll never let go, Jack. I'll never let go. I promise.\n");
printk("Device released\n");
return 0;
}
/* End from hello.c*/
// Compatibility with device tree
static struct of_device_id matchy_match[] = {
{
.compatible = "gpiod_driver",
},
{/* leave alone - keep this here (end node) */},
};
// Platform driver object
static struct platform_driver adam_driver = {
.probe = led_probe,
.remove = led_remove,
.driver = {
.name = "The Rock: this name doesn't even matter",
.owner = THIS_MODULE,
.of_match_table = matchy_match, // edited
},
};
module_platform_driver(adam_driver); // edited
MODULE_DESCRIPTION("424\'s finest");
MODULE_AUTHOR("GOAT");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:adam_driver");
// module_init(hello_init);
// module_exit(hello_exit);
Comments
Please log in or sign up to comment.