Файл «Frenet_frame.py» представляет собой основной скрипт для запуска ровера и управления его движением. Он содержит функции для планирования траектории, управления ровером и взаимодействия с внешними системами.
asyncio: библиотека для работы с асинхронными операциями в Python.
json: библиотека для работы с форматом JSON.
socket: библиотека для работы с сетевыми сокетами.
threading: библиотека для работы с многопоточностью.
tracemalloc: библиотека для отслеживания использования памяти.
math: библиотека для математических операций.
sys: библиотека для работы с системными функциями.
pathlib: библиотека для работы с файловыми путями.
numpy: библиотека для работы с числами и массивами.
matplotlib: библиотека для создания графиков и визуализации данных.
plotly: библиотека для создания интерактивных графиков и визуализации данных.
video_processing: отдельный код для работы с видеопотоком (см. раздел "Нейронная сеть и машинное зрение" -> Описание программы машинного зрения -> ФАЙЛ "VIDEO_PROCESSING")
Realsense: класс, хранящийся в файле video_processing.
tornado: библиотека для создания веб-серверов и работы с веб-сокетами.
quintic_polynomials_planner: отдельный код для работы с методом навигации (см. раздел "Описание навигационной части программы (одномерное пространство и математическое вычисление пути)" -> Навигация методом математических вычислений на графике -> ФАЙЛ "QUINTIC_POLYNOMIALS_PLANNER.PY")
cubic_spline_planner: отдельный код для работы с методом навигации (см. раздел "Описание навигационной части программы (одномерное пространство и математическое вычисление пути)" -> Навигация в одномерном пространстве (график) -> ФАЙЛ «CUBIC_SPLINE_PLANNER.PY»)
ИНИЦИАЛИЗАЦИЯ КЛАССА
Атрибуты:
a0 (float): Свободный член полинома, начальное положение.
a1 (float): Коэффициент при первой степени t, начальная скорость.
a2 (float): Коэффициент при второй степени t, половина начального ускорения.
a3 (float): Коэффициент при третьей степени t.
a4 (float): Коэффициент при четвертой степени t.
Этот класс представляет собой квартический полином, используемый для планирования траектории ровера. При инициализации класса передаются начальные условия: положение, скорость и ускорение.
МЕТОД ПОСТРОЕНИЯ ТРАЕКТОРИИ
Этот метод генерирует пути в координатах Френе на основе заданных начальных и конечных условий. Он используется для планирования траектории ровера.
МЕТОД ПРЕОБРАЗОВАНИЯ ТРАЕКТОРИИ
Параметры:
- fplist (list of FrenetPath objects): Список объектов путей в системе координат Френе.
- csp (CubicSpline2D object): Объект кубического сплайна для пути.
Этот метод преобразует пути из координат Френе в глобальные координаты. Он используется для преобразования траектории ровера в глобальные координаты.
МЕТОД ПРОВЕРКИ СТОЛКНОВЕНИЯ
Параметры:
- fp (FrenetPath object): Объект пути в системе координат Френе.
- ob (numpy.ndarray): Массив препятствий, где каждое препятствие представлено координатами (x, y).
Этот метод проверяет столкновение траектории с препятствиями. Он используется для проверки безопасности траектории ровера.
МЕТОД ПРОВЕРКИ ПУТЕЙ И ОТСУТСТВИЕ ПРЕПЯТСТВИЙ
Параметры:
- fplist (list of FrenetPath objects): Список объектов путей в системе координат Френе.
- ob (list of tuples): Список препятствий в формате (x, y).
Функция итерируется по каждому пути в списке и проверяет его на соответствие максимальной скорости и кривизне.
МЕТОД ПЛАНИРОВАНИЯ ТРАЕКТОРИИ
Параметры:
- csp (CubicSpline2D object): Объект кубического сплайна, представляющий путь.
- s0 (float): Начальное значение длины дуги на сплайне.
- c_d_dd (float): Текущая вторая производная бокового смещения.
- ob (list of tuples): Список препятствий в формате (x, y).
Этот метод планирует оптимальную траекторию в системе координат Френе. Он используется для планирования траектории ровера.
МЕТОД ГЕНЕРАЦИИ ЦЕЛЕВОГО КУРСА
Параметры:
- x (list): Список X-координат.
- y (list): Список Y-координат.
Этот метод генерирует целевой курс с использованием кубического сплайна. Он используется для генерации целевого курса для ровера.
МЕТОД ВЫЧИСЛЕНИЯ УГЛА
Этот метод вычисляет угол между начальной и конечной точками. Он используется для вычисления угла между начальной и конечной точками траектории ровера.
МЕТОД ОБРАБОТКИ ДАННЫХ О МАССЕ
Параметры:
- xs (float): X-координата начальной точки.
- ys (float): Y-координата начальной точки.
- tar (float): Целевой угол в градусах.
Функция пытается получить данные с помощью метода `give_mass`. В случае ошибки
используется заранее определённый массив данных. Затем функция ищет точки,
у которых расстояние до некоторой цели приблизительно равно 0.5 (с допуском 0.2).
МЕТОД ВЫЧИСЛЕНИЯ УГЛА МЕЖДУ НАЧАЛЬНОЙ И КОНЕЧНОЙ ТОЧКАМИ
Параметры:
- x (float): X-координата начальной точки.
- y (float): Y-координата начальной точки.
- dxs (float): X-координата конечной точки.
- dys (float): Y-координата конечной точки.
Этот метод вычисляет угол между начальной и конечной точками. Он используется для вычисления угла между начальной и конечной точками траектории ровера.
МЕТОД ЗАПУСКА РОВЕРА
Параметры:
- x (float): Начальная координата X объекта.
- y (float): Начальная координата Y объекта.
- dx (float): Конечная координата X объекта.
- dy (float): Конечная координата Y объекта.
- con (object): Объект управления, который может быть использован для отправки команд управления.
Функция `main` инициализирует начальное состояние объекта и планирует траекторию от начальной до конечной точки.
Она учитывает статические препятствия и использует метод оптимального планирования Френе для генерации пути.
В процессе планирования функция может адаптировать траекторию, если обнаруживаются новые препятствия.
Результаты планирования визуализируются с помощью библиотеки Plotly, если установлен флаг `show_animation`.
Функция также поддерживает отправку команд управления через объект `con`, если он предоставлен.
КЛАСС ЗАПУСКА С ВНЕШНЕГО ФАЙЛА
Процесс подготовки кода:
Создайте файл с названием Frenet_frame.py
Файл Frenet_frame.py в окне иерархии
Поэтапно копируйте код в файл:
Окно программирования в файле frenet_frame.py. Часть 1
Окно программирования в файле frenet_frame.py. Часть 2
Окно программирования в файле frenet_frame.py. Часть 3
Окно программирования в файле frenet_frame.py. Часть 4
Окно программирования в файле frenet_frame.py. Часть 5
Окно программирования в файле frenet_frame.py. Часть 6
Окно программирования в файле frenet_frame.py. Часть 7
Окно программирования в файле frenet_frame.py. Часть 8
Окно программирования в файле frenet_frame.py. Часть 9
Окно программирования в файле frenet_frame.py. Часть 10
Окно программирования в файле frenet_frame.py. Часть 11
Окно программирования в файле frenet_frame.py. Часть 12
Окно программирования в файле frenet_frame.py. Часть 13
Окно программирования в файле frenet_frame.py. Часть 14
Окно программирования в файле frenet_frame.py. Часть 15
Окно программирования в файле frenet_frame.py. Часть 16
Окно программирования в файле frenet_frame.py. Часть 17
Окно программирования в файле frenet_frame.py. Часть 18
Установите необходимые библиотеки: в данном случае в Python не предустановлены следующие библиотеки: matplotlib, numpy, plotly, tornado. Если эти библиотеки у вас не установлены, следуйте следующим шагам:
Откройте терминал в Visual Studio Code (Terminal -> New Terminal или комбинацией Ctrl + Shift + `)
Пропишите в терминал данные команды (записывать и запускать поочередно!): pip install numpy; pip install matplotlib; pip install tornado
Запускать код нет смысла, так как он является алгоритмизацией движения ровера.
class QuarticPolynomial:
def __init__(self, xs, vxs, axs, vxe, axe, time):
self.a0 = xs
self.a1 = vxs
self.a2 = axs / 2.0
A = np.array([[3 * time ** 2, 4 * time ** 3],
[6 * time, 12 * time ** 2]])
b = np.array([vxe - self.a1 - 2 * self.a2 * time,
axe - 2 * self.a2])
x = np.linalg.solve(A, b)
self.a3 = x[0]
self.a4 = x[1]
def calc_frenet_paths(c_speed, c_accel, c_d, c_d_d, c_d_dd, s0):
frenet_paths = []
# generate path to each offset goal
for di in np.arange(-MAX_ROAD_WIDTH, MAX_ROAD_WIDTH, D_ROAD_W):
# Lateral motion planning
for Ti in np.arange(MIN_T, MAX_T, DT):
fp = FrenetPath()
# lat_qp = quintic_polynomial(c_d, c_d_d, c_d_dd, di, 0.0, 0.0, Ti)
lat_qp = QuinticPolynomial(c_d, c_d_d, c_d_dd, di, 0.0, 0.0, Ti)
fp.t = [t for t in np.arange(0.0, Ti, DT)]
fp.d = [lat_qp.calc_point(t) for t in fp.t]
fp.d_d = [lat_qp.calc_first_derivative(t) for t in fp.t]
fp.d_dd = [lat_qp.calc_second_derivative(t) for t in fp.t]
fp.d_ddd = [lat_qp.calc_third_derivative(t) for t in fp.t]
# Longitudinal motion planning (Velocity keeping)
for tv in np.arange(TARGET_SPEED - D_T_S * N_S_SAMPLE,
TARGET_SPEED + D_T_S * N_S_SAMPLE, D_T_S):
tfp = copy.deepcopy(fp)
lon_qp = QuarticPolynomial(s0, c_speed, c_accel, tv, 0.0, Ti)
tfp.s = [lon_qp.calc_point(t) for t in fp.t]
tfp.s_d = [lon_qp.calc_first_derivative(t) for t in fp.t]
tfp.s_dd = [lon_qp.calc_second_derivative(t) for t in fp.t]
tfp.s_ddd = [lon_qp.calc_third_derivative(t) for t in fp.t]
Jp = sum(np.power(tfp.d_ddd, 2)) # square of jerk
Js = sum(np.power(tfp.s_ddd, 2)) # square of jerk
# square of diff from target speed
ds = (TARGET_SPEED - tfp.s_d[-1]) ** 2
tfp.cd = K_J * Jp + K_T * Ti + K_D * tfp.d[-1] ** 2
tfp.cv = K_J * Js + K_T * Ti + K_D * ds
tfp.cf = K_LAT * tfp.cd + K_LON * tfp.cv
frenet_paths.append(tfp)
return frenet_paths
def calc_global_paths(fplist, csp):
for fp in fplist:
# calc global positions
for i in range(len(fp.s)):
ix, iy = csp.calc_position(fp.s[i])
if ix is None:
break
i_yaw = csp.calc_yaw(fp.s[i])
di = fp.d[i]
fx = ix + di * math.cos(i_yaw + math.pi / 2.0)
fy = iy + di * math.sin(i_yaw + math.pi / 2.0)
fp.x.append(fx)
fp.y.append(fy)
# calc yaw and ds
for i in range(len(fp.x) - 1):
dx = fp.x[i + 1] - fp.x[i]
dy = fp.y[i + 1] - fp.y[i]
fp.yaw.append(math.atan2(dy, dx))
fp.ds.append(math.hypot(dx, dy))
fp.yaw.append(fp.yaw[-1])
fp.ds.append(fp.ds[-1])
# calc curvature
for i in range(len(fp.yaw) - 1):
fp.c.append((fp.yaw[i + 1] - fp.yaw[i]) / fp.ds[i])
return fplist
def check_collision(fp, ob):
for i in range(len(ob[:, 0])):
d = [((ix - ob[i, 0]) ** 2 + (iy - ob[i, 1]) ** 2)
for (ix, iy) in zip(fp.x, fp.y)]
collision = any([di <= ROBOT_RADIUS ** 2 for di in d])
if collision:
return False
return True
def check_paths(fplist, ob):
ok_ind = []
for i, _ in enumerate(fplist):
if any([v > MAX_SPEED for v in fplist[i].s_d]): # Max speed check
continue
elif any([abs(c) > MAX_CURVATURE for c in
fplist[i].c]): # Max curvature check
continue
elif not check_collision(fplist[i], ob):
continue
ok_ind.append(i)
return [fplist[i] for i in ok_ind]