Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
- name: Install linting tools
run: |
python -m pip install --upgrade pip
pip install ruff black isort
pip install ruff black isort mypy

- name: Check code formatting with Black
run: black --check src/aylm tests
Expand All @@ -69,3 +69,6 @@ jobs:

- name: Lint with Ruff
run: ruff check src/aylm tests

- name: Type check with mypy (informational)
run: mypy src/aylm --ignore-missing-imports || echo "mypy found issues (non-blocking)"
4,488 changes: 4,488 additions & 0 deletions .output.txt

Large diffs are not rendered by default.

796 changes: 608 additions & 188 deletions README.md

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions configs/constitution_example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# A-YLM 宪法配置示例
# 用户可以根据自己的需求修改此配置

# 宪法原则列表
principles:
# 碰撞检测 - 最高优先级
- name: no_collision
severity: critical
enabled: true
params:
check_trajectory: true
prediction_horizon: 2.0 # 预测时间范围(秒)

# TTC 安全 - 高优先级
- name: ttc_safety
severity: high
enabled: true
params:
warning_threshold: 3.0 # 警告阈值(秒)
critical_threshold: 1.5 # 关键阈值(秒)

# 安全跟车距离
- name: safe_following
severity: high
enabled: true
params:
time_gap: 2.0 # 时间间隔(秒)

# 车道合规
- name: lane_compliance
severity: medium
enabled: true

# 速度限制
- name: speed_limit
severity: medium
enabled: true
params:
max_speed: 120 # km/h

# 安全阈值
thresholds:
ttc_warning: 3.0 # TTC 警告阈值(秒)
ttc_critical: 1.5 # TTC 关键阈值(秒)
min_safe_distance: 2.0 # 最小安全距离(米)
speed_distance_factor: 0.5 # 速度-距离系数

# 打分权重
weights:
collision: 1.0 # 碰撞权重
ttc: 0.8 # TTC 权重
boundary: 0.5 # 边界权重

# 训练信号配置
training:
generate_positive_signals: false # 是否生成正样本
export_format: json # 导出格式: json, tfrecord, parquet
110 changes: 110 additions & 0 deletions fuse.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash
# 多帧点云融合脚本
# 用法: ./fuse.sh [输入目录] [输出文件]

set -e

# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 默认路径
DEFAULT_INPUT="outputs/video_output/voxelized"
DEFAULT_OUTPUT="outputs/video_output/fused_map.ply"

# 解析参数
INPUT_DIR="${1:-$DEFAULT_INPUT}"
OUTPUT_FILE="${2:-$DEFAULT_OUTPUT}"

# 显示帮助
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
echo "多帧点云融合脚本"
echo ""
echo "用法: ./fuse.sh [输入目录] [输出文件] [选项]"
echo ""
echo "参数:"
echo " 输入目录 包含 vox_*.ply 文件的目录 (默认: $DEFAULT_INPUT)"
echo " 输出文件 融合后的点云文件路径 (默认: $DEFAULT_OUTPUT)"
echo ""
echo "选项:"
echo " -h, --help 显示帮助"
echo ""
echo "示例:"
echo " ./fuse.sh # 使用默认路径"
echo " ./fuse.sh outputs/my_scan # 指定输入目录"
echo " ./fuse.sh outputs/my_scan my_map.ply # 指定输入和输出"
echo ""
echo "高级用法 (直接调用 aylm):"
echo " aylm fuse -i 输入目录 -o 输出文件 --icp-distance 0.1 --voxel-size 0.05"
exit 0
fi

# 检查输入目录
if [[ ! -d "$INPUT_DIR" ]]; then
echo -e "${YELLOW}错误: 输入目录不存在: $INPUT_DIR${NC}"
exit 1
fi

# 统计点云文件
PLY_COUNT=$(find "$INPUT_DIR" -name "vox_*.ply" 2>/dev/null | wc -l | tr -d ' ')

if [[ "$PLY_COUNT" -eq 0 ]]; then
echo -e "${YELLOW}错误: 未找到 vox_*.ply 文件${NC}"
echo "目录: $INPUT_DIR"
exit 1
fi

# 显示信息
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}多帧点云融合${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "输入目录: ${GREEN}$INPUT_DIR${NC}"
echo -e "点云数量: ${GREEN}$PLY_COUNT${NC} 帧"
echo -e "输出文件: ${GREEN}$OUTPUT_FILE${NC}"
echo ""

# 列出点云文件
echo "点云文件:"
find "$INPUT_DIR" -name "vox_*.ply" | sort | while read f; do
SIZE=$(du -h "$f" | cut -f1)
echo " $(basename "$f") ($SIZE)"
done
echo ""

# 激活虚拟环境
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -d "$SCRIPT_DIR/aylm_env" ]]; then
source "$SCRIPT_DIR/aylm_env/bin/activate"
fi

# 执行融合
echo -e "${BLUE}开始融合...${NC}"
echo ""

aylm fuse -i "$INPUT_DIR" -o "$OUTPUT_FILE" -v

# 检查结果
if [[ -f "$OUTPUT_FILE" ]]; then
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}融合完成!${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"

OUTPUT_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
echo ""
echo -e "输出文件: ${GREEN}$OUTPUT_FILE${NC} ($OUTPUT_SIZE)"

# 检查位姿文件
POSES_FILE="${OUTPUT_FILE%.ply}.poses.json"
if [[ -f "$POSES_FILE" ]]; then
echo -e "位姿轨迹: ${GREEN}$POSES_FILE${NC}"
fi

echo ""
echo "查看结果:"
echo " open $OUTPUT_FILE # macOS 默认应用打开"
echo " meshlab $OUTPUT_FILE # 使用 MeshLab 查看"
fi
50 changes: 49 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "aylm"
version = "2.0.0"
description = "AYLM - Advanced YLM for 3D Gaussian Splatting"
description = "A-YLM: Geometric Constitutional AI for Embodied Intelligence - Bidirectional fusion with E2E driving systems (FSD/ADS), providing 3D point cloud input and safety supervision. Self-supervised learning without human annotation. Edge-deployable real-time geometric validation."
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.9"
Expand All @@ -20,6 +20,8 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Scientific/Engineering :: Image Recognition",
"Topic :: Scientific/Engineering :: Visualization",
]
dependencies = [
"numpy",
Expand All @@ -41,9 +43,11 @@ semantic = [
]
dev = [
"pytest",
"pytest-cov",
"black",
"isort",
"ruff",
"mypy",
]
all = [
"open3d>=0.18.0",
Expand All @@ -68,3 +72,47 @@ line_length = 88
[tool.ruff]
line-length = 88
target-version = "py39"

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"RUF", # Ruff-specific rules
]
ignore = [
"E501", # line too long (handled by black)
"B008", # function call in default argument
"B905", # zip without strict
"RUF001", # ambiguous unicode in string (中文逗号等)
"RUF002", # ambiguous unicode in docstring
"RUF003", # ambiguous unicode in comment
"RUF022", # __all__ not sorted (按功能分组更清晰)
"TC002", # move import into TYPE_CHECKING (运行时需要)
]

[tool.ruff.lint.isort]
known-first-party = ["aylm"]

[tool.mypy]
python_version = "3.11"
warn_return_any = false
warn_unused_configs = true
disallow_untyped_defs = false
check_untyped_defs = false
ignore_missing_imports = true
exclude = [
"tests/",
"ml-sharp/",
"aylm_env/",
]

[[tool.mypy.overrides]]
module = "yaml"
ignore_missing_imports = true
22 changes: 19 additions & 3 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ ${YELLOW}点云切片选项:${NC}
--no-slice 禁用点云切片
--slice-radius 切片半径/米 (默认: 10.0)

${YELLOW}目标跟踪选项:${NC}
--track 启用目标跟踪 (默认)
--no-track 禁用目标跟踪

${YELLOW}示例:${NC}
./run.sh --setup # 初始化
./run.sh -i ./images # 处理图像
Expand Down Expand Up @@ -158,9 +162,10 @@ run_auto() {
main() {
local action="auto" input_dir="inputs/input_images" output_dir="" config_file=""
local extra_args=() check_only=false use_gpu=false frame_interval="" fps="10" loop=false
# 语义检测和切片参数(默认都启用)
local semantic=true semantic_model="yolo11n-seg.pt" semantic_confidence="0.5"
# 语义检测、切片和跟踪参数(默认都启用)
local semantic=true semantic_model="yolo11n-seg.pt" semantic_confidence="0.25"
local slice=true slice_radius="10.0"
local track=true

while [[ $# -gt 0 ]]; do
case "$1" in
Expand All @@ -185,6 +190,9 @@ main() {
--slice) slice=true; shift ;;
--no-slice) slice=false; shift ;;
--slice-radius) slice_radius="$2"; shift 2 ;;
# 跟踪参数
--track) track=true; shift ;;
--no-track) track=false; shift ;;
*) extra_args+=("$1"); shift ;;
esac
done
Expand Down Expand Up @@ -213,6 +221,13 @@ main() {
slice_args+=("--no-slice")
fi

local track_args=()
if [[ "$track" == true ]]; then
track_args+=("--track")
else
track_args+=("--no-track")
fi

case "$action" in
setup) log_step "下载模型..."; python3 -m aylm.cli setup --download ;;
voxelize) run_voxelize "${extra_args[@]}" ;;
Expand All @@ -223,6 +238,7 @@ main() {
local video_args=("${extra_args[@]}")
[[ -n "$config_file" ]] && video_args+=("-c" "$config_file")
[[ "$use_gpu" == true ]] && video_args+=("--use-gpu")
video_args+=("${semantic_args[@]}" "${slice_args[@]}" "${track_args[@]}")
show_banner "视频处理"
run_video_process "${video_args[@]}" ;;
video-extract)
Expand All @@ -234,7 +250,7 @@ main() {
local play_args=("-i" "$input_dir" "--fps" "$fps")
[[ "$loop" == true ]] && play_args+=("--loop")
run_video_play "${play_args[@]}" ;;
auto) run_auto "$input_dir" "${extra_args[@]}" "${semantic_args[@]}" "${slice_args[@]}" ;;
auto) run_auto "$input_dir" "${extra_args[@]}" "${semantic_args[@]}" "${slice_args[@]}" "${track_args[@]}" ;;
esac

log_info "完成"
Expand Down
Loading