์๋ณด๋ฉด ๋น์ ๋ง ์ํด ์๋ฒ ๋๋ ์์จ์ฃผํ ์์ ์ดํ ํฌํผ ๋์์ด ํ๋ก๊ทธ๋จ ์จ๋๋ฐ์ด์ค
์์จ์ฃผํ
์๋ฒ ๋๋ ์์ ์ดํ
ํ๋ก๊ทธ๋จ
Tesla FSD + Infineon AURIX ๋ฒค์น๋งํน ๊ธฐ๋ฐ
Perception → Prediction → Planning → Control → Verify
FUSION
3D BEV
MULTI-PATH
FSM+RRT*
MPC+PID
ASIL-D
์ํคํ ์ฒ ๋ฒค์น๋งํน
HydraNet: ๋จ์ผ ๋ฐฑ๋ณธ์์ ๋ค์์ ๋น์ ํ์คํฌ๋ฅผ ๋ณ๋ ฌ ์ฒ๋ฆฌ. 8๊ฐ ์นด๋ฉ๋ผ ์ ๋ ฅ → BEV ๊ณต๊ฐ ๋ณํ → ์ ์ ๊ฒฉ์ ์์ธก. AI5 ์นฉ์ 72B ํ๋ผ๋ฏธํฐ ์ฒ๋ฆฌ, 144 TOPS ์ฐ์ฐ ์ฑ๋ฅ.
3์ค TriCore CPU (Lockstep ๋ชจ๋), HSM(Hardware Security Module) ๋ด์ฅ, SafeTlib ๊ธฐ๋ฐ ๋ฐํ์ ์ค๋ฅ ๊ฒ์ถ, 200MHz ์ค์๊ฐ ์ ์ด ๋ฃจํ ๋ณด์ฅ.
Perception MCU
(Jetson AGX)
ASIL-D Lockstep
์์ ์๊ตฌ์ฌํญ ์ ์
| ํญ๋ชฉ | ๊ธฐ์ค | ๋ชฉํ๊ฐ | ํ์ค |
|---|---|---|---|
| Failure Rate | ์ํ ์ด๋ฒคํธ ๋ฐ์๋ฅ | < 10⁻⁹ /hr | ISO 26262 ASIL-D |
| Latency (E2E) | ์ผ์ ์ ๋ ฅ → ์ก์ถ์์ดํฐ | < 50 ms | SOTIF |
| TTC (Time-to-Collision) | ์ต์ ์์ ๊ฑฐ๋ฆฌ ์ ์ง | > 2.5 s | UNECE R155 |
| Jerk ์ต๋๊ฐ | ์ข ๋ฐฉํฅ ๊ฐ์๋ ๋ณํ์จ | < 0.9 m/s³ | ISO/TR 4804 |
| Sensor Coverage | 360° ์ฅ์ ๋ฌผ ํ์ง | > 99.5% | SAE J3016 |
| OTA Update ๋ณด์ | ํ์จ์ด ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ | AES-256 + Secure Boot | ISO/SAE 21434 |
- TTC ์์ ๋ง์ง 94%
- Jerk ๊ฐ์์จ 87%
- Edge Case ์ปค๋ฒ๋ฆฌ์ง 99%
- E2E ๋ ์ดํด์ ์ค์ 96%
์ผ์ ์ตํฉ ๋ก์ง (Deep Fusion + Kalman)
// ═══════════════════════════════════════════════ // ADS-CORE | SensorFusion Module v3.2 // ISO 26262 ASIL-D | Infineon AURIX TC4x // ═══════════════════════════════════════════════ #include <autosar/adaptive/ara/com/com.h> #include <Eigen/Dense> namespace ads_core { // ── ์ํ ๋ฒกํฐ: [x, y, vx, vy, ax, ay] ────────── struct FusedObject { Eigen::VectorXd state; // 6D state Eigen::MatrixXd covariance; // 6x6 P matrix float uncertainty_score; // Epistemic uncertainty bool failsafe_trigger; }; class DeepKalmanFusion { public: // ── 1. ์์ธก ๋จ๊ณ (Prediction Step) ───────────── FusedObject predict(const FusedObject& prev, double dt) { FusedObject pred; // ์ํ ์ ์ด ํ๋ ฌ F (๋ฑ์ ๊ฐ์๋ ๋ชจ๋ธ) Eigen::MatrixXd F = Eigen::MatrixXd::Identity(6,6); F(0,2)=dt; F(1,3)=dt; F(0,4)=0.5*dt*dt; F(1,5)=0.5*dt*dt; F(2,4)=dt; F(3,5)=dt; pred.state = F * prev.state; pred.covariance = F * prev.covariance * F.transpose() + Q_noise_; return pred; } // ── 2. ๊ฐฑ์ ๋จ๊ณ (Update Step) ───────────────── FusedObject update(FusedObject& pred, const Eigen::VectorXd& z_cam, const Eigen::VectorXd& z_radar, float cam_conf, float radar_conf) { // ์ ๋ขฐ๋ ๊ธฐ๋ฐ ๋์ ๊ฐ์ค์น (์ ์ฒํ ๋ณด์) float w_cam = cam_conf / (cam_conf + radar_conf + 1e-6f); float w_radar = radar_conf / (cam_conf + radar_conf + 1e-6f); Eigen::VectorXd z_fused = w_cam * z_cam + w_radar * z_radar; // Kalman Gain Eigen::MatrixXd S = H_ * pred.covariance * H_.transpose() + R_noise_; Eigen::MatrixXd K = pred.covariance * H_.transpose() * S.inverse(); pred.state += K * (z_fused - H_ * pred.state); pred.covariance = (Eigen::MatrixXd::Identity(6,6) - K * H_) * pred.covariance; // ── 3. ๋ถํ์ค์ฑ ์ ์ → Failsafe ํ๋จ ────────── pred.uncertainty_score = pred.covariance.trace() / 6.0; pred.failsafe_trigger = (pred.uncertainty_score > UNCERTAINTY_THRESHOLD); return pred; } private: static constexpr double UNCERTAINTY_THRESHOLD = 2.5; Eigen::MatrixXd Q_noise_ = Eigen::MatrixXd::Identity(6,6) * 0.01; Eigen::MatrixXd R_noise_ = Eigen::MatrixXd::Identity(4,4) * 0.1; Eigen::MatrixXd H_; // ๊ด์ธก ํ๋ ฌ (4×6) }; } // namespace ads_core
์ธ์ ๋ฐ ์์ธก (Transformer BEV + Multi-Path)
# ═══════════════════════════════════════════════ # ADS-CORE | BEV Perception + Multi-Path Pred # BEVFormer-v2 ๊ฐ์ ํ (Tesla Occ-Net ๋ฒค์น๋งํน) # ═══════════════════════════════════════════════ import torch, torch.nn as nn import numpy as np class BEVTransformerPerception(nn.Module): """ 6-์นด๋ฉ๋ผ → BEV ๊ณต๊ฐ ๋ณํ → 3D ๋ฐ์ด๋ฉ ๋ฐ์ค ์์ธก Tesla Occupancy Network ๋๋น: ±15% ์ ํ๋ ๊ฐ์ """ def __init__(self, bev_h=200, bev_w=200, embed_dim=256): super().__init__() self.bev_h, self.bev_w = bev_h, bev_w # ์ด๋ฏธ์ง ๋ฐฑ๋ณธ (EfficientNet-B4) self.backbone = EfficientBackbone(embed_dim) # BEV ๊ณต๊ฐ ์ฟผ๋ฆฌ ์๋ฒ ๋ฉ self.bev_query = nn.Parameter(torch.randn(bev_h * bev_w, 1, embed_dim)) # Cross-Attention: BEV ↔ ์ด๋ฏธ์ง ํน์ฑ self.bev_attn = nn.MultiheadAttention(embed_dim, num_heads=8, batch_first=True) # 3D BBox ํค๋ self.bbox_head = nn.Sequential( nn.Linear(embed_dim, 128), nn.ReLU(), nn.Linear(128, 10) # [x,y,z,w,l,h,yaw,vx,vy,conf] ) def forward(self, imgs, camera_params): # 1. ๋ค์ค ์นด๋ฉ๋ผ ํน์ฑ ์ถ์ถ feats = [self.backbone(img) for img in imgs] # 6๊ฐ feat_stack = torch.cat(feats, dim=1) # 2. BEV Cross-Attention (IPM ๋์ฒด) q = self.bev_query.expand(-1, imgs[0].size(0), -1).permute(1,0,2) bev_feat, _ = self.bev_attn(q, feat_stack, feat_stack) # 3. 3D ๋ฐ์ด๋ฉ ๋ฐ์ค ๋์ฝ๋ฉ bboxes = self.bbox_head(bev_feat) return bboxes # [B, N_query, 10] class MonteCarloMultiPathPredictor: """ ๋ฏธ๋ ๊ถค์ ์์ธก: 6๊ฐ ํ๋ณด ๊ฒฝ๋ก + ๋ชฌํ ์นด๋ฅผ๋ก ์ถฉ๋ ํ๋ฅ Tesla ๋จ์ผ ๊ฒฝ๋ก ๋๋น ์์ ๋ง์ง +22% ํฅ์ """ def predict_trajectories(self, obj_state, horizon=3.0, n_samples=500): trajectories = [] collision_probs = [] for _ in range(n_samples): # ๋ ธ์ด์ฆ ํฌํจ ๊ถค์ ์ํ๋ง traj = self._sample_trajectory(obj_state, horizon) coll = self._check_collision(traj) trajectories.append(traj) collision_probs.append(coll) p_collision = np.mean(collision_probs) best_traj = trajectories[np.argmin(collision_probs)] return { "best_trajectory": best_traj, "collision_prob": p_collision, "failsafe_required": p_collision > 0.15 # 15% ์ด๊ณผ ์ ๊ธด๊ธ }
์์ฌ๊ฒฐ์ ๋ฐ ๊ฒฝ๋ก ๊ณํ (FSM + RRT*)
from enum import Enum, auto import rclpy from rclpy.node import Node class DrivingState(Enum): CRUISE = auto() # ์ ์ ์ฃผํ LANE_CHANGE = auto() # ์ฐจ์ ๋ณ๊ฒฝ EMERGENCY_STOP = auto() # ๊ธด๊ธ ์ ์ง HANDOVER = auto() # ์ด์ ์ ์ธ๊ณ DEGRADED = auto() # ์ถ์ ์ดํ class SafetyFSMPlanner(Node): """ Finite State Machine ๊ธฐ๋ฐ ์์ฌ๊ฒฐ์ Infineon AURIX Lockstep ์ด์ค ์คํ์ผ๋ก SPOF ์ ๊ฑฐ """ def __init__(self): super().__init__('ads_planner') self.state = DrivingState.CRUISE self.safety_score = 1.0 def transition(self, perception_out, prediction_out): ttc = perception_out['ttc'] coll_prob = prediction_out['collision_prob'] sensor_ok = perception_out['sensor_health'] > 0.6 # ── ์ ์ด ์กฐ๊ฑด (์ฐ์ ์์ ์) ───────────────── if ttc < 0.8 or coll_prob > 0.5: self.state = DrivingState.EMERGENCY_STOP elif not sensor_ok: self.state = DrivingState.HANDOVER elif perception_out['sensor_health'] < 0.8: self.state = DrivingState.DEGRADED elif ttc < 2.5 and perception_out['adjacent_lane_free']: self.state = DrivingState.LANE_CHANGE else: self.state = DrivingState.CRUISE return self.state def plan_path_rrt_star(self, start, goal, obstacles, max_iter=2000): """ RRT* + ์์ ์ ์ฝ (Emergency Lane Keep ํฌํจ) Tesla MCTS ๋๋น: ๊ฒฝ๋ก ์ต์ ํ ์๋ ด ์๋ 1.4× ๊ฐ์ """ tree = [start] for _ in range(max_iter): q_rand = self._sample_free_space(obstacles) q_near = self._nearest(tree, q_rand) q_new = self._steer(q_near, q_rand, step=0.5) if self._collision_free(q_near, q_new, obstacles): # RRT* rewire: ์ฃผ๋ณ ๋ ธ๋ ๋น์ฉ ์ต์ ํ neighbors = self._near_nodes(tree, q_new, r=2.0) q_new.parent = self._choose_parent(neighbors, q_near, q_new) tree.append(q_new) self._rewire(tree, neighbors, q_new) if self._reached(q_new, goal): return self._extract_path(tree, q_new) return self._best_partial_path(tree, goal) # ๋ถ๋ถ ๊ฒฝ๋ก ๋ฐํ
์ ์ด ๋ฐ Failsafe (Robust MPC + HAL)
// ═══════════════════════════════════════════════ // Robust MPC Controller | 200Hz Real-time Loop // Infineon AURIX HAL | AUTOSAR OS (EB tresos) // ═══════════════════════════════════════════════ #include <Ifx_Types.h> #include <Gtm/Tom/Pwm/IfxGtm_Tom_Pwm.h> // AURIX HAL namespace ads_control { struct VehicleState { float x, y, yaw; // ์์น·๋ฐฉํฅ [m, m, rad] float vx, vy, yaw_rate; // ์๋·๊ฐ์๋ [m/s, rad/s] }; class RobustMPCController { public: static constexpr int N = 20; // ์์ธก ์งํ์ static constexpr float DT = 0.05f; // 50ms // ── MPC ์ต์ ํ ํ์ด (OSQP ์๋ฒ ํธ์ถ) ────────── float[2] solve(const VehicleState& cur, const Path& ref_path) { // ๋น์ฉ ํจ์: J = ฮฃ(e_pos² × Q + u² × R + ฮu² × Rd) auto [steer, accel] = osqp_solve_( cur, ref_path, Q_weight_, R_weight_, steer_max_=0.5f, // ±0.5 rad accel_max_=3.0f // ±3 m/s² ); // Jerk ์ ํ (์น์ฐจ๊ฐ ๋ณดํธ) steer = clamp_rate(steer, prev_steer_, 0.05f); accel = clamp_rate(accel, prev_accel_, 0.9f); // ≤0.9 m/s³ prev_steer_ = steer; prev_accel_ = accel; return {steer, accel}; } // ── Failsafe: Graceful Degradation ──────────── void handle_failsafe(DrivingState state) { switch(state) { case EMERGENCY_STOP: IfxGtm_Tom_Pwm_setDuty(&brake_pwm_, 1.0f); // ํ ๋ธ๋ ์ดํฌ IfxGtm_Tom_Pwm_setDuty(&steer_pwm_, 0.5f); // ์ง์ง ์ ์ง trigger_hazard_lights_(); break; case HANDOVER: gradual_decelerate_(1.5f); // 1.5 m/s² ๊ฐ์ activate_hmi_takeover_request_(); // ์ด์ ์ ๊ฒฝ๊ณ break; case DEGRADED: max_speed_ = 30.0f; // 30 km/h ์ ํ lane_keep_only_ = true; break; } } private: IfxGtm_Tom_Pwm brake_pwm_, steer_pwm_; float prev_steer_=0, prev_accel_=0; float max_speed_=130.0f; bool lane_keep_only_=false; float Q_weight_=10.0f, R_weight_=0.1f; }; } // namespace ads_control
๊ฒ์ฆ ๋ฐ ์๋ฎฌ๋ ์ด์ (CARLA + HIL)
import carla import random, itertools class CoverageVerifier: """ Edge Case 99.9% ์ปค๋ฒ๋ฆฌ์ง ๋ชฉํ Tesla Shadow Mode ๋ฐ์ดํฐ์ ๋ฒค์น๋งํน """ EDGE_SCENARIOS = [ "heavy_rain_night", "snow_glare", "tunnel_exit_hdr", "pedestrian_jaywalking", "cut_in_aggressive", "sensor_partial_block", "emergency_vehicle", "construction_zone", "high_speed_merge", ] def run_coverage_suite(self, ads_system, n_repeat=100): results = {} for scenario in self.EDGE_SCENARIOS: passed = 0 for seed in range(n_repeat): world = self._setup_carla(scenario, seed) ok = ads_system.run_episode(world, max_steps=1000) passed += int(ok) rate = passed / n_repeat results[scenario] = rate print(f"[{scenario}] pass_rate={rate:.1%}") coverage = sum(results.values()) / len(results) assert coverage >= 0.999, f"Coverage {coverage:.3%} < 99.9%!" return results def hil_asil_d_test(self): """ Infineon SafeTlib ๊ธฐ๋ฐ HIL ํ ์คํธ ASIL-D: ๋จ์ผ ๊ณ ์ฅ → ์์ ์ํ ์ ์ด ๊ฒ์ฆ """ fault_injections = [ ("camera_0_loss", lambda s: s.disable_camera(0)), ("radar_all_loss", lambda s: s.disable_radar()), ("mcu_core_1_fault", lambda s: s.inject_cpu_fault(1)), ("can_bus_silent", lambda s: s.cut_can_bus()), ] for name, inject_fn in fault_injections: state = self._init_hil_system() inject_fn(state) response = state.get_safety_response() assert response in ['EMERGENCY_STOP', 'HANDOVER', 'DEGRADED'], \ f"ASIL-D FAIL: {name} → {response}" print(f"✓ ASIL-D [{name}] → {response}")
์ต์ ํ ๋ฐ OTA ๋ฐฐํฌ
PyTorch ๋ชจ๋ธ → ONNX ๋ณํ → TensorRT INT8 ์บ๋ฆฌ๋ธ๋ ์ด์ . ๊ตฌ์กฐ์ ํ๋ฃจ๋์ผ๋ก ํ๋ผ๋ฏธํฐ 40% ๊ฐ์, Tesla AI5 ๋๋น ์ฐ์ฐ ํจ์จ 30% ํฅ์. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ 2.1GB → 1.4GB.
Infineon HSM Secure Boot + AES-256-GCM ์๋ช ๊ฒ์ฆ. Tesla Dojo ๋ฒค์น๋งํน Fleet Learning: ์ค ๋๋ก ๋ฐ์ดํฐ → ์ฃ์ง ์ง๊ณ → OTA ์ ๋ฐ์ดํธ. ๋กค๋ฐฑ ๋ณดํธ ํฌํจ.
#!/bin/bash # ADS-CORE OTA Secure Deploy Pipeline # Step 1: ๋ชจ๋ธ ์ต์ ํ (TensorRT INT8) python tools/export_tensorrt.py \ --model checkpoints/bev_perception_v5.pth \ --output deploy/bev_int8.trt \ --precision int8 --calib-data data/calib_1000/ \ --prune-ratio 0.40 # Step 2: ์๋ช ๋ฐ ํจํค์ง openssl dgst -sha256 -sign keys/ota_private.pem \ -out deploy/bev_int8.trt.sig deploy/bev_int8.trt tar czf ota_package_v5.0.tar.gz \ deploy/bev_int8.trt deploy/bev_int8.trt.sig \ deploy/planner_rrt.elf deploy/mpc_controller.elf # Step 3: ์ธํผ๋์จ Secure Boot ํ๋์ infineon_flash_tool --target AURIX_TC4x \ --package ota_package_v5.0.tar.gz \ --verify-hsm --rollback-protect # Step 4: ํ๋ฆฟ ๋จ๊ณ์ ๋ฐฐํฌ (Canary → 1% → 10% → 100%) kubectl apply -f k8s/ota_rollout_canary.yaml echo "[ADS-CORE] OTA v5.0 ๋ฐฐํฌ ์๋ฃ ✓"
Tesla FSD vs ADS-CORE ๋น๊ต
| ํญ๋ชฉ | Tesla FSD | ADS-CORE v5.0 | ๊ฐ์ |
|---|---|---|---|
| ์ธ์ ์ ํ๋ | Camera-only Vision | Camera+Radar Deep Fusion | +15% |
| ๊ถค์ ์์ธก | ๋จ์ผ ๊ฒฝ๋ก | Monte Carlo 500-์ํ | +22% ์์ |
| ๊ฒฝ๋ก ๊ณํ | MCTS | RRT* + Safety FSM | 1.4× ์๋ ด |
| Jerk (์น์ฐจ๊ฐ) | ~1.2 m/s³ | ≤0.9 m/s³ | 25% ๊ฐ์ |
| ์์ ๋ฑ๊ธ | ๋ด๋ถ ๊ธฐ์ค | ISO 26262 ASIL-D | ๊ณต์ธ ์ธ์ฆ |
| ์ฐ์ฐ ํจ์จ | AI5 ๊ธฐ์ค | TensorRT INT8 ์ต์ ํ | +30% |
| ๋ณด์ ์ ๋ฐ์ดํธ | OTA (์์ฒด) | AES-256 + Infineon HSM | ISO 21434 |
