auto_drive_misson_center_we.../path_generate_json.py
2026-10-04 18:12:20 +08:00

217 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import math
import matplotlib.pyplot as plt
# ============================================================
# 参数配置
# ============================================================
# 起点:采用你提供的第一个路径点
START_LAT = 30.80062100422322
START_LON = 121.21541599992909
TURN_RADIUS = 1.5
MISSION_SPEED = 0.32
ARC_SPACING = 0.3
# 地球半径(m)
EARTH_RADIUS = 6378137.0
#
first_line_length = 6.0
first_arc_rad = math.pi # 180° 半圆
second_line_length = 8.0
second_arc_rad = math.pi / 2 # 90° 四分之一圆
third_line_length = 5.0
# ============================================================
# 工具函数
# ============================================================
def normalize_yaw(yaw):
"""将 yaw 归一化到 [-pi, pi]。"""
return math.atan2(math.sin(yaw), math.cos(yaw))
def local_to_latlon(x, y):
"""
局部 ENU 坐标转经纬度。
x: East,向东为正,单位 m
y: North,向北为正,单位 m
"""
lat0 = math.radians(START_LAT)
lat = START_LAT + math.degrees(y / EARTH_RADIUS)
lon = START_LON + math.degrees(
x / (EARTH_RADIUS * math.cos(lat0))
)
return lat, lon
def add_point(points, x, y, yaw):
"""添加一个 [latitude, longitude, yaw] 路径点。"""
lat, lon = local_to_latlon(x, y)
points.append([
round(lat, 12),
round(lon, 12),
round(normalize_yaw(yaw), 9)
])
def add_arc(points, cx, cy, radius,
start_angle, sweep_angle, spacing):
"""
添加圆弧采样点,不重复添加圆弧起点。
yaw 为圆弧的切线方向,单位 rad。
"""
arc_length = abs(radius * sweep_angle)
num_segments = max(1, math.ceil(arc_length / spacing))
for i in range(1, num_segments + 1):
ratio = i / num_segments
angle = start_angle + sweep_angle * ratio
x = cx + radius * math.cos(angle)
y = cy + radius * math.sin(angle)
# CCW 左转时,切线方向 = 圆心角 + pi/2
yaw = angle + (
math.pi / 2 if sweep_angle > 0
else -math.pi / 2
)
add_point(points, x, y, yaw)
coordinates = []
# 1. 第一段直线:长度 6 m
# 起点 (0, 0),终点 (6, 0)
add_point(coordinates, 0, 0, 0.0)
add_point(coordinates, first_line_length, 0, 0.0)
# 第一段圆弧起始索引
first_turn_index = len(coordinates) - 1
# 2. 第一段半圆:R=1,逆时针 180°
# 圆心 (6, 1),从 -90° 转到 90°
add_arc(
coordinates,
cx=first_line_length,
cy=TURN_RADIUS,
radius=TURN_RADIUS,
start_angle=-math.pi / 2,
sweep_angle= first_arc_rad,
spacing=ARC_SPACING
)
# 3. 第二段直线:长度 8 m
# 半圆终点 (6, 2),直线终点 (-2, 2)
second_line_end_x = first_line_length - second_line_length
second_line_end_y = 2 * TURN_RADIUS
add_point(
coordinates,
second_line_end_x,
second_line_end_y,
math.pi
)
# 第二段圆弧起始索引
second_turn_index = len(coordinates) - 1
# 4. 第二段四分之一圆:顺时针 90°
# 与第一段圆弧方向相反
second_arc_cx = second_line_end_x
second_arc_cy = second_line_end_y + TURN_RADIUS
add_arc(
coordinates,
cx=second_arc_cx,
cy=second_arc_cy,
radius=TURN_RADIUS,
start_angle=-math.pi / 2,
sweep_angle=-second_arc_rad,
spacing=ARC_SPACING
)
# 5. 最后一段直线:长度 5 m
third_line_start_x = second_arc_cx
third_line_start_y = second_arc_cy
add_point(
coordinates,
third_line_start_x - TURN_RADIUS,
third_line_start_y + third_line_length,
math.pi / 2
)
# ============================================================
# 构造符合现有项目的 GeoJSON
# ============================================================
path_json = {
"type": "FeatureCollection",
"properties": {
"turnRadius": TURN_RADIUS,
"misionSpeed": MISSION_SPEED
},
"features": [
{
"type": "Feature",
"properties": {
"turnInds": [
first_turn_index,
second_turn_index
],
"mission": []
},
"geometry": {
"type": "LineString",
"coordinates": coordinates
}
}
]
}
# ============================================================
# 保存文件
# ============================================================
output_file = "test_path.json"
with open(output_file, "w", encoding="utf-8") as f:
json.dump(
path_json,
f,
ensure_ascii=False,
indent=2
)
print(f"JSON 文件已生成: {output_file}")
print(f"路径点数量: {len(coordinates)}")
print(f"turnInds: {path_json['features'][0]['properties']['turnInds']}")
print(f"起点: {coordinates[0]}")
print(f"终点: {coordinates[-1]}")
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot([p[0] for p in coordinates], [p[1] for p in coordinates], "-o", markersize=3, label="Path")
ax.set_xlabel("X (m)")
ax.set_ylabel("Y (m)")
ax.axis("equal")
ax.grid(True)
ax.legend()
plt.tight_layout()
plt.show()