2024-12-27 16:10:25 +01:00
|
|
|
from OpenGL.images import returnFormat
|
2024-12-25 16:52:07 +01:00
|
|
|
from adafruit_hcsr04 import HCSR04 as hcsr04
|
|
|
|
|
import board
|
|
|
|
|
import data_transfer_functions as dt
|
|
|
|
|
from adafruit_servokit import ServoKit
|
|
|
|
|
import numpy as np
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
from scipy.integrate import odeint
|
|
|
|
|
import numpy as np
|
|
|
|
|
import matplotlib.pyplot as plt
|
2024-12-27 16:10:25 +01:00
|
|
|
import statistics as st
|
2024-12-25 16:52:07 +01:00
|
|
|
|
|
|
|
|
# Variables to control sensor
|
|
|
|
|
TRIGGER_PIN = board.D4
|
|
|
|
|
ECHO_PIN = board.D17
|
|
|
|
|
TIMEOUT = 0.1
|
|
|
|
|
MIN_DISTANCE = 4
|
|
|
|
|
MAX_DISTANCE = 40
|
|
|
|
|
|
|
|
|
|
# Variables to control logging.
|
|
|
|
|
LOG = True
|
|
|
|
|
SCREEN = True
|
2024-12-27 16:10:25 +01:00
|
|
|
DEBUG = False
|
2024-12-25 16:52:07 +01:00
|
|
|
|
|
|
|
|
# PID measurements
|
|
|
|
|
time = 0
|
|
|
|
|
integral = 0
|
|
|
|
|
time_prev = -1e-6
|
|
|
|
|
e_prev = 0
|
|
|
|
|
|
2024-12-27 16:10:25 +01:00
|
|
|
# PID values
|
|
|
|
|
P_value = 2
|
|
|
|
|
I_value = 0
|
|
|
|
|
D_value = 0
|
|
|
|
|
|
|
|
|
|
sample_array = []
|
2024-12-25 16:52:07 +01:00
|
|
|
|
|
|
|
|
def initial():
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def read_distance_sensor(fixed_file_stamp):
|
|
|
|
|
|
|
|
|
|
with (hcsr04(trigger_pin=TRIGGER_PIN, echo_pin=ECHO_PIN, timeout=TIMEOUT) as sonar):
|
2024-12-27 16:10:25 +01:00
|
|
|
samples = 0
|
|
|
|
|
max_samples = 10
|
|
|
|
|
timestamp_last = 0.0
|
|
|
|
|
timestamp_first = 0.0
|
|
|
|
|
while samples != max_samples:
|
2024-12-25 16:52:07 +01:00
|
|
|
try:
|
|
|
|
|
distance = sonar.distance
|
|
|
|
|
if MIN_DISTANCE < distance < MAX_DISTANCE:
|
|
|
|
|
|
|
|
|
|
dt.log_data(fixed_file_stamp,"sensor", distance, None) if LOG else None
|
2024-12-27 16:10:25 +01:00
|
|
|
print("Distance: ", distance) if SCREEN else None
|
|
|
|
|
|
|
|
|
|
sample_array.append(distance)
|
|
|
|
|
if samples == 0: timestamp_first, _ = dt.timestamper()
|
|
|
|
|
if samples == max_samples - 1: timestamp_last, _ = dt.timestamper()
|
|
|
|
|
|
|
|
|
|
timestamp_first_float = float(timestamp_first)
|
|
|
|
|
timestamp_last_float = float(timestamp_last)
|
|
|
|
|
samples = samples + 1
|
|
|
|
|
median_distance = st.median(sample_array)
|
|
|
|
|
mean_timestamp = st.mean([timestamp_first_float, timestamp_last_float])
|
|
|
|
|
print(median_distance) if LOG else None
|
|
|
|
|
print(mean_timestamp)
|
|
|
|
|
|
2024-12-25 16:52:07 +01:00
|
|
|
else:
|
2024-12-27 16:10:25 +01:00
|
|
|
dt.log_data(fixed_file_stamp,"sensor", distance,"Ignored") if LOG and DEBUG else None
|
2024-12-25 16:52:07 +01:00
|
|
|
print("Distance: ", distance) if SCREEN else None
|
|
|
|
|
|
|
|
|
|
except RuntimeError:
|
2024-12-27 16:10:25 +01:00
|
|
|
dt.log_data(fixed_file_stamp, "sensor", 999.999, "Timeout") if LOG and DEBUG else None
|
2024-12-25 16:52:07 +01:00
|
|
|
print("Timeout") if SCREEN else None
|
|
|
|
|
|
2024-12-27 16:10:25 +01:00
|
|
|
return median_distance, mean_timestamp
|
|
|
|
|
|
2024-12-25 16:52:07 +01:00
|
|
|
def read_setpoint():
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def calculate_velocity():
|
2024-12-27 16:10:25 +01:00
|
|
|
...
|
2024-12-25 16:52:07 +01:00
|
|
|
|
2024-12-27 16:10:25 +01:00
|
|
|
def PID_calculations(setpoint):
|
2024-12-25 16:52:07 +01:00
|
|
|
|
2024-12-27 16:10:25 +01:00
|
|
|
global I_result, previous_time, previous_error
|
2024-12-25 16:52:07 +01:00
|
|
|
offset_value = 320
|
2024-12-27 16:10:25 +01:00
|
|
|
measurement, current_time = read_distance_sensor
|
2024-12-25 16:52:07 +01:00
|
|
|
error = setpoint - measurement
|
2024-12-27 16:10:25 +01:00
|
|
|
|
|
|
|
|
if previous_time is None:
|
|
|
|
|
previous_error: float = 0.0
|
|
|
|
|
previous_time: float = current_time
|
|
|
|
|
I_result: float = 0.0
|
|
|
|
|
error_sum: float = error * 0.008 # sensor sampling number approximation.
|
|
|
|
|
|
|
|
|
|
error_sum: float = error_sum + (error * (current_time - previous_time))
|
|
|
|
|
P_result: float = P_value * error
|
|
|
|
|
I_result: float = I_value * error_sum
|
|
|
|
|
D_result: float = D_value * ((error - previous_error) / (current_time - previous_time))
|
|
|
|
|
PID_result: float = offset_value + P_result + I_result + D_result
|
|
|
|
|
previous_error: float = error
|
|
|
|
|
previous_time: float = current_time
|
|
|
|
|
|
2024-12-25 16:52:07 +01:00
|
|
|
return PID_result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def calculate_new_servo_pos():
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_data_to_servo():
|
|
|
|
|
|
|
|
|
|
kit = ServoKit(channels=16)
|
|
|
|
|
kit.servo[0].set_pulse_width_range(500, 2500)
|
|
|
|
|
|
|
|
|
|
kit.servo[0].angle = 180
|
|
|
|
|
|