Eunice TanNicolas RossiJuan GarzaVedant Patwari
Published © GPL3+

The NicoMobile

Have you ever wanted to make your remote-controlled car run by itself? Nico and Others (dubbed, 'Team YoungerWoods') have done it! :)

AdvancedFull instructions provided298
The NicoMobile

Things used in this project

Hardware components

BeagleBone AI-64
BeagleBoard.org BeagleBone AI-64
×1
USB WiFi Adapter
×1
Webcam, Logitech® HD Pro
Webcam, Logitech® HD Pro
×1
Portable Battery Charger
×1

Software apps and online services

OpenCV
OpenCV – Open Source Computer Vision Library OpenCV

Story

Read more

Code

Main function

Python
'''

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=}")

PWM Class

Python
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()

Data Collection

Python
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]

Data Plotting

Python
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()

Overlay

C/C++
// 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>;
	};
};

GPIOD Driver

C/C++
#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);

The NicoMobile

The code developed for this project

Credits

Eunice Tan
2 projects • 1 follower
Contact
Nicolas Rossi
2 projects • 0 followers
Contact
Juan Garza
2 projects • 0 followers
Contact
Vedant Patwari
1 project • 0 followers
Contact

Comments

Please log in or sign up to comment.