From b3608ecfd7dd02565bbfde037f92c1e65a3d86d7 Mon Sep 17 00:00:00 2001 From: thebadking Date: Wed, 21 Oct 2026 06:04:46 +0000 Subject: [PATCH] Rename the simulator to Overwatch and organize the repository for presentation. The operator interface now uses that name. The radar design, parts list, and simulation sit in separate directories, and the earlier simulator and project license are removed. Co-authored-by: Cursor --- .github/workflows/ci-tests.yml | 10 +- .gitignore | 60 +- CONTRIBUTING.md | 26 +- DEFENSE_SIMULATION.md | 206 - Licence | 154 - README.md | 283 +- debug2.js | 57 - debug_sim.js | 162 - defense_sim.html | 1368 -- defense_sim.py | 701 - defense_sim_v2/frontend/LICENSE | 21 - .../frontend/src/types/simulation.ts | 50 - defense_sim_v2/src/defense_sim/__init__.py | 3 - .../src/defense_sim/entities/drone.py | 325 - .../src/defense_sim/guidance/ascent.py | 30 - .../src/defense_sim/guidance/trajectory.py | 221 - .../src/defense_sim/sensors/devices.py | 165 - .../src/defense_sim/simulation/engine.py | 782 - .../tests/test_audit_regressions.py | 271 - .../tests/test_standby_and_trails.py | 101 - .../te0713-te0701-heartbeat-2026-03-21.md | 2 +- .../te0713-te0701-umft601x-dev-2026-03-21.md | 8 +- ...-te0701-umft601x-dev-timing-2026-03-21.rpt | 2 +- docs/reports.html | 12 +- dual_radar_tracking_results.png | Bin 199960 -> 0 bytes .../9_1_1_C_Cpp_Libraries/ADAR1000_AGC.cpp | 0 .../9_1_1_C_Cpp_Libraries/ADAR1000_AGC.h | 0 .../ADAR1000_Manager.cpp | 52 +- .../9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h | 0 .../9_1_1_C_Cpp_Libraries/ADS7830.H | 0 .../9_1_1_C_Cpp_Libraries/ADS7830.c | 0 .../9_1_1_C_Cpp_Libraries/BMP180.cpp | 0 .../9_1_1_C_Cpp_Libraries/BMP180.h | 0 .../9_1_1_C_Cpp_Libraries/DA5578.c | 0 .../9_1_1_C_Cpp_Libraries/DAC5578.H | 0 .../9_1_1_C_Cpp_Libraries/GY_85_HAL.c | 0 .../9_1_1_C_Cpp_Libraries/GY_85_HAL.h | 0 .../9_1_1_C_Cpp_Libraries/RadarSettings.cpp | 0 .../9_1_1_C_Cpp_Libraries/RadarSettings.h | 0 .../9_1_1_C_Cpp_Libraries/TinyGPS++.cpp | 0 .../9_1_1_C_Cpp_Libraries/TinyGPS++.h | 0 .../9_1_1_C_Cpp_Libraries/TinyGPSPlus.h | 0 .../9_1_1_C_Cpp_Libraries/USBHandler.cpp | 0 .../9_1_1_C_Cpp_Libraries/USBHandler.h | 0 .../9_1_1_C_Cpp_Libraries/ad9523.c | 0 .../9_1_1_C_Cpp_Libraries/ad9523.h | 0 .../9_1_1_C_Cpp_Libraries/adf4382.c | 0 .../9_1_1_C_Cpp_Libraries/adf4382.h | 0 .../9_1_1_C_Cpp_Libraries/adf4382a_manager.c | 0 .../9_1_1_C_Cpp_Libraries/adf4382a_manager.h | 0 .../9_1_1_C_Cpp_Libraries/diag_log.h | 0 .../9_1_1_C_Cpp_Libraries/errno.h | 0 .../9_1_1_C_Cpp_Libraries/gps_handler.cpp | 0 .../9_1_1_C_Cpp_Libraries/gps_handler.h | 0 .../9_1_1_C_Cpp_Libraries/iio.c | 0 .../9_1_1_C_Cpp_Libraries/iio.h | 0 .../9_1_1_C_Cpp_Libraries/iio_app.c | 0 .../9_1_1_C_Cpp_Libraries/iio_app.h | 0 .../9_1_1_C_Cpp_Libraries/iio_trigger.c | 0 .../9_1_1_C_Cpp_Libraries/iio_trigger.h | 0 .../9_1_1_C_Cpp_Libraries/iio_types.h | 0 .../9_1_1_C_Cpp_Libraries/iiod.c | 0 .../9_1_1_C_Cpp_Libraries/iiod.h | 0 .../9_1_1_C_Cpp_Libraries/iiod_private.h | 0 .../9_1_1_C_Cpp_Libraries/jesd204.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_ain.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_alloc.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_alloc.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_aout.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_axi_io.h | 0 .../no_os_circular_buffer.c | 0 .../no_os_circular_buffer.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_clk.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_clk.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc16.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc16.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc24.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc24.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc8.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_crc8.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_delay.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_dma.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_dma.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_eeprom.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_eeprom.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_error.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_fifo.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_fifo.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_flash.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_font_8x8.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_gpio.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_gpio.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_i2c.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_i2c.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_i3c.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_i3c.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_init.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_irq.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_irq.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_list.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_list.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_mdio.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_mdio.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_mutex.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_mutex.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_pid.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_pid.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_print_log.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_pwm.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_pwm.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_rtc.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_semaphore.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_semaphore.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_sin_lut.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_spi.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_spi.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_tdm.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_tdm.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_timer.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_timer.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_trng.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_trng.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_uart.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_uart.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_units.h | 0 .../9_1_1_C_Cpp_Libraries/no_os_util.c | 0 .../9_1_1_C_Cpp_Libraries/no_os_util.h | 0 .../platform_noos_stm32.H | 0 .../platform_noos_stm32.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_delay.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_delay.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_dma.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_dma.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_gpio.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_gpio.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_hal.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_i2c.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_i2c.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_irq.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_irq.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_pwm.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_pwm.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_spi.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_spi.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_timer.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_timer.h | 0 .../9_1_1_C_Cpp_Libraries/stm32_uart.c | 0 .../9_1_1_C_Cpp_Libraries/stm32_uart.h | 0 .../stm32f7xx_hal_conf.h | 0 .../9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c | 0 .../9_1_1_C_Cpp_Libraries/stm32f7xx_it.c | 0 .../9_1_1_C_Cpp_Libraries/stm32f7xx_it.h | 0 .../9_1_1_C_Cpp_Libraries/syscalls.c | 0 .../9_1_1_C_Cpp_Libraries/sysmem.c | 0 .../9_1_1_C_Cpp_Libraries/system_stm32f7xx.c | 0 .../9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx | 0 .../9_1_3_C_Cpp_Code/main.cpp | 0 .../9_1_3_C_Cpp_Code/main.h | 0 .../9_1_3_C_Cpp_Code/um982_gps.c | 0 .../9_1_3_C_Cpp_Code/um982_gps.h | 0 .../9_1_Microcontroller/tests/.gitignore | 0 .../9_1_Microcontroller/tests/Makefile | 0 .../tests/ad_driver_mock.c | 0 .../tests/ad_driver_mock.h | 0 .../9_1_Microcontroller/tests/shims/adf4382.h | 0 .../tests/shims/adf4382a_manager.h | 0 .../tests/shims/diag_log.h | 0 .../9_1_Microcontroller/tests/shims/main.h | 0 .../tests/shims/no_os_delay.h | 0 .../tests/shims/no_os_spi.h | 0 .../tests/shims/no_os_units.h | 0 .../tests/shims/no_os_util.h | 0 .../tests/shims/platform_noos_stm32.h | 0 .../tests/shims/stm32_spi.h | 0 .../tests/shims/stm32f7xx_hal.h | 0 .../tests/stm32_hal_mock.c | 0 .../tests/stm32_hal_mock.h | 0 .../tests/test_agc_outer_loop.cpp | 0 .../tests/test_bug10_spi_cs_not_toggled.c | 0 .../test_bug11_platform_spi_transmit_only.c | 0 .../tests/test_bug12_pa_cal_loop_inverted.c | 0 .../test_bug13_dac2_adc_buffer_mismatch.c | 0 .../tests/test_bug14_diag_section_args.c | 0 .../tests/test_bug15_htim3_dangling_extern.c | 0 .../test_bug1_timed_sync_init_ordering.c | 0 .../tests/test_bug2_ad9523_double_setup.c | 0 .../tests/test_bug3_timed_sync_noop.c | 0 .../test_bug4_phase_shift_before_check.c | 0 .../tests/test_bug5_fine_phase_gpio_only.c | 0 .../test_bug6_timer_variable_collision.c | 0 .../tests/test_bug7_gpio_pin_conflict.c | 0 .../tests/test_bug8_uart_commented_out.c | 2 +- .../tests/test_bug9_platform_ops_null.c | 0 .../test_gap3_emergency_state_ordering.c | 0 .../tests/test_gap3_emergency_stop_rails.c | 0 .../test_gap3_health_watchdog_cold_start.c | 0 .../tests/test_gap3_idq_periodic_reread.c | 0 .../tests/test_gap3_iwdg_config.c | 0 .../tests/test_gap3_overtemp_emergency_stop.c | 0 .../tests/test_gap3_temperature_max.c | 0 .../tests/test_um982_gps.c | 0 {9_Firmware => firmware}/9_2_FPGA/.gitignore | 0 .../9_2_FPGA/ad9484_interface_400m.v | 0 .../9_2_FPGA/adc_clk_mmcm.v | 0 .../9_2_FPGA/adc_clk_mmcm_integration.md | 0 .../9_2_FPGA/cdc_modules.v | 0 {9_Firmware => firmware}/9_2_FPGA/cfar_ca.v | 0 .../9_2_FPGA/chirp_memory_loader_param.v | 0 .../9_2_FPGA/cic_decimator_4x_enhanced.v | 0 .../9_2_FPGA/constraints/README.md | 2 +- .../9_2_FPGA/constraints/adc_clk_mmcm.xdc | 0 .../9_2_FPGA/constraints/debug_ila.xdc | 0 .../constraints/te0712_te0701_minimal.xdc | 0 .../constraints/te0713_te0701_minimal.xdc | 0 .../constraints/te0713_te0701_umft601x.xdc | 0 .../9_2_FPGA/constraints/xc7a200t_fbg484.xdc | 0 .../9_2_FPGA/constraints/xc7a50t_ftg256.xdc | 0 .../9_2_FPGA/dac_interface_single.v | 0 {9_Firmware => firmware}/9_2_FPGA/ddc_400m.v | 0 .../9_2_FPGA/ddc_input_interface.v | 0 .../9_2_FPGA/doppler_processor.v | 0 .../9_2_FPGA/edge_detector.v | 0 .../9_2_FPGA/fft_engine.v | 0 .../9_2_FPGA/fft_twiddle_1024.mem | 0 .../9_2_FPGA/fft_twiddle_16.mem | 0 .../9_2_FPGA/fir_lowpass.v | 0 .../9_2_FPGA/formal/fv_cdc_adc.sby | 0 .../9_2_FPGA/formal/fv_cdc_adc.v | 0 .../9_2_FPGA/formal/fv_cdc_handshake.sby | 0 .../9_2_FPGA/formal/fv_cdc_handshake.v | 0 .../formal/fv_cdc_handshake_cover.sby | 0 .../9_2_FPGA/formal/fv_cdc_single_bit.sby | 0 .../9_2_FPGA/formal/fv_cdc_single_bit.v | 0 .../9_2_FPGA/formal/fv_doppler_processor.sby | 0 .../9_2_FPGA/formal/fv_doppler_processor.v | 0 .../formal/fv_radar_mode_controller.sby | 0 .../formal/fv_radar_mode_controller.v | 0 .../formal/fv_range_bin_decimator.sby | 0 .../9_2_FPGA/formal/fv_range_bin_decimator.v | 0 .../9_2_FPGA/fpga_self_test.v | 0 .../9_2_FPGA/frequency_matched_filter.v | 0 .../9_2_FPGA/latency_buffer.v | 0 .../9_2_FPGA/long_chirp_lut.mem | 0 .../9_2_FPGA/long_chirp_seg0_i.mem | 0 .../9_2_FPGA/long_chirp_seg0_q.mem | 0 .../9_2_FPGA/long_chirp_seg1_i.mem | 0 .../9_2_FPGA/long_chirp_seg1_q.mem | 0 .../9_2_FPGA/long_chirp_seg2_i.mem | 0 .../9_2_FPGA/long_chirp_seg2_q.mem | 0 .../9_2_FPGA/long_chirp_seg3_i.mem | 0 .../9_2_FPGA/long_chirp_seg3_q.mem | 0 .../9_2_FPGA/matched_filter_multi_segment.v | 0 .../matched_filter_processing_chain.v | 0 .../9_2_FPGA/mti_canceller.v | 0 .../9_2_FPGA/nco_400m_enhanced.v | 0 .../9_2_FPGA/plfm_chirp_controller.v | 0 .../9_2_FPGA/radar_mode_controller.v | 0 .../9_2_FPGA/radar_receiver_final.v | 0 .../9_2_FPGA/radar_system_top.v | 0 .../9_2_FPGA/radar_system_top_50t.v | 0 .../9_2_FPGA/radar_system_top_te0712_dev.v | 0 .../9_2_FPGA/radar_system_top_te0713_dev.v | 0 .../radar_system_top_te0713_umft601x_dev.v | 0 .../9_2_FPGA/radar_transmitter.v | 0 .../9_2_FPGA/range_bin_decimator.v | 0 .../9_2_FPGA/run_regression.sh | 0 .../9_2_FPGA/rx_gain_control.v | 0 .../9_2_FPGA/scripts/200t/build_200t.tcl | 2 +- .../9_2_FPGA/scripts/50t/build_50t.tcl | 2 +- .../scripts/te0712/build_te0712_dev.tcl | 0 .../scripts/te0713/build_te0713_dev.tcl | 0 .../te0713/build_te0713_umft601x_dev.tcl | 0 .../9_2_FPGA/scripts/utils/ila_capture.tcl | 0 .../scripts/utils/insert_ila_probes.tcl | 0 .../9_2_FPGA/scripts/utils/program_fpga.tcl | 0 .../scripts/utils/run_cdc_and_netlist.tcl | 0 .../9_2_FPGA/short_chirp_i.mem | 0 .../9_2_FPGA/short_chirp_q.mem | 0 .../9_2_FPGA/tb/ad9484_interface_400m_stub.v | 0 .../9_2_FPGA/tb/cic_dc_output.csv | 0 .../9_2_FPGA/tb/cic_impulse_output.csv | 0 .../9_2_FPGA/tb/cic_sine_passband.csv | 0 .../9_2_FPGA/tb/cosim/adc_dc.hex | 0 .../9_2_FPGA/tb/cosim/adc_multi_target.hex | 0 .../9_2_FPGA/tb/cosim/adc_noise_only.hex | 0 .../9_2_FPGA/tb/cosim/adc_sine_1mhz.hex | 0 .../9_2_FPGA/tb/cosim/adc_single_target.hex | 0 .../9_2_FPGA/tb/cosim/bb_mf_test_i.hex | 0 .../9_2_FPGA/tb/cosim/bb_mf_test_q.hex | 0 .../9_2_FPGA/tb/cosim/compare.py | 0 .../9_2_FPGA/tb/cosim/compare_dc.csv | 0 .../9_2_FPGA/tb/cosim/compare_doppler.py | 0 .../9_2_FPGA/tb/cosim/compare_mf.py | 0 .../9_2_FPGA/tb/cosim/compare_mf_chirp.csv | 0 .../9_2_FPGA/tb/cosim/compare_mf_dc.csv | 0 .../9_2_FPGA/tb/cosim/compare_mf_impulse.csv | 0 .../9_2_FPGA/tb/cosim/compare_mf_tone5.csv | 0 .../tb/cosim/compare_multi_target.csv | 0 .../9_2_FPGA/tb/cosim/compare_noise_only.csv | 0 .../9_2_FPGA/tb/cosim/compare_sine_1mhz.csv | 0 .../tb/cosim/compare_single_target.csv | 0 .../tb/cosim/doppler_golden_py_moving.csv | 0 .../tb/cosim/doppler_golden_py_moving.hex | 0 .../tb/cosim/doppler_golden_py_stationary.csv | 0 .../tb/cosim/doppler_golden_py_stationary.hex | 0 .../cosim/doppler_golden_py_two_targets.csv | 0 .../cosim/doppler_golden_py_two_targets.hex | 0 .../tb/cosim/doppler_input_moving.hex | 0 .../tb/cosim/doppler_input_stationary.hex | 0 .../tb/cosim/doppler_input_two_targets.hex | 0 .../9_2_FPGA/tb/cosim/fpga_model.py | 0 .../9_2_FPGA/tb/cosim/gen_chirp_mem.py | 0 .../9_2_FPGA/tb/cosim/gen_doppler_golden.py | 2 +- .../9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py | 2 +- .../9_2_FPGA/tb/cosim/gen_multiseg_golden.py | 0 .../9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv | 0 .../9_2_FPGA/tb/cosim/mf_golden_py_dc.csv | 0 .../tb/cosim/mf_golden_py_i_chirp.hex | 0 .../9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex | 0 .../tb/cosim/mf_golden_py_i_impulse.hex | 0 .../tb/cosim/mf_golden_py_i_tone5.hex | 0 .../tb/cosim/mf_golden_py_impulse.csv | 0 .../tb/cosim/mf_golden_py_q_chirp.hex | 0 .../9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex | 0 .../tb/cosim/mf_golden_py_q_impulse.hex | 0 .../tb/cosim/mf_golden_py_q_tone5.hex | 0 .../9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv | 0 .../9_2_FPGA/tb/cosim/mf_ref_dc_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_ref_dc_q.hex | 0 .../9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex | 0 .../9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_dc_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_dc_q.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex | 0 .../9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_golden.csv | 0 .../tb/cosim/multiseg_golden_seg0_i.hex | 0 .../tb/cosim/multiseg_golden_seg0_q.hex | 0 .../tb/cosim/multiseg_golden_seg1_i.hex | 0 .../tb/cosim/multiseg_golden_seg1_q.hex | 0 .../tb/cosim/multiseg_golden_seg2_i.hex | 0 .../tb/cosim/multiseg_golden_seg2_q.hex | 0 .../tb/cosim/multiseg_golden_seg3_i.hex | 0 .../tb/cosim/multiseg_golden_seg3_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_input_i.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_input_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex | 0 .../9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex | 0 .../tb/cosim/multiseg_short_golden.csv | 0 .../tb/cosim/multiseg_short_golden_i.hex | 0 .../tb/cosim/multiseg_short_golden_q.hex | 0 .../tb/cosim/multiseg_short_input_i.hex | 0 .../tb/cosim/multiseg_short_input_q.hex | 0 .../tb/cosim/multiseg_short_ref_i.hex | 0 .../tb/cosim/multiseg_short_ref_q.hex | 0 .../9_2_FPGA/tb/cosim/radar_scene.py | 0 .../tb/cosim/real_data/golden_reference.py | 0 .../tb/cosim/real_data/hex/STALE_NOTICE.md | 2 +- .../tb/cosim/real_data/hex/adc_chirp0.hex | 0 .../tb/cosim/real_data/hex/chirp0_i.hex | 0 .../tb/cosim/real_data/hex/chirp0_q.hex | 0 .../cosim/real_data/hex/decimated_range_i.hex | 0 .../cosim/real_data/hex/decimated_range_i.npy | Bin .../cosim/real_data/hex/decimated_range_q.hex | 0 .../cosim/real_data/hex/decimated_range_q.npy | Bin .../tb/cosim/real_data/hex/detection_mag.npy | Bin .../tb/cosim/real_data/hex/detections.txt | 0 .../real_data/hex/doppler_input_realdata.hex | 0 .../tb/cosim/real_data/hex/doppler_map_i.hex | 0 .../tb/cosim/real_data/hex/doppler_map_i.npy | Bin .../tb/cosim/real_data/hex/doppler_map_q.hex | 0 .../tb/cosim/real_data/hex/doppler_map_q.npy | Bin .../tb/cosim/real_data/hex/doppler_ref_i.hex | 0 .../tb/cosim/real_data/hex/doppler_ref_q.hex | 0 .../real_data/hex/fullchain_cfar_det.hex | 0 .../hex/fullchain_cfar_detections.txt | 0 .../real_data/hex/fullchain_cfar_flags.npy | Bin .../real_data/hex/fullchain_cfar_mag.hex | 0 .../real_data/hex/fullchain_cfar_mag.npy | Bin .../real_data/hex/fullchain_cfar_thr.hex | 0 .../real_data/hex/fullchain_cfar_thr.npy | Bin .../real_data/hex/fullchain_detection_mag.hex | 0 .../real_data/hex/fullchain_detections.txt | 0 .../real_data/hex/fullchain_doppler_i.npy | Bin .../real_data/hex/fullchain_doppler_q.npy | Bin .../real_data/hex/fullchain_doppler_ref_i.hex | 0 .../hex/fullchain_doppler_ref_packed.hex | 0 .../real_data/hex/fullchain_doppler_ref_q.hex | 0 .../real_data/hex/fullchain_mti_doppler_i.npy | Bin .../real_data/hex/fullchain_mti_doppler_q.npy | Bin .../hex/fullchain_mti_doppler_ref_i.hex | 0 .../hex/fullchain_mti_doppler_ref_q.hex | 0 .../cosim/real_data/hex/fullchain_mti_i.npy | Bin .../cosim/real_data/hex/fullchain_mti_q.npy | Bin .../real_data/hex/fullchain_mti_ref_i.hex | 0 .../real_data/hex/fullchain_mti_ref_q.hex | 0 .../real_data/hex/fullchain_notched_ref_i.hex | 0 .../hex/fullchain_notched_ref_packed.hex | 0 .../real_data/hex/fullchain_notched_ref_q.hex | 0 .../real_data/hex/fullchain_range_input.hex | 0 .../tb/cosim/real_data/hex/post_ddc_i.hex | 0 .../tb/cosim/real_data/hex/post_ddc_q.hex | 0 .../cosim/real_data/hex/range_fft_all_i.npy | Bin .../cosim/real_data/hex/range_fft_all_q.npy | Bin .../real_data/hex/range_fft_chirp0_i.hex | 0 .../real_data/hex/range_fft_chirp0_q.hex | 0 .../9_2_FPGA/tb/cosim/ref_chirp_i.hex | 0 .../9_2_FPGA/tb/cosim/ref_chirp_q.hex | 0 .../9_2_FPGA/tb/cosim/rtl_bb_dc.csv | 0 .../9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv | 0 .../9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv | 0 .../9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv | 0 .../tb/cosim/rtl_bb_single_target.csv | 0 .../9_2_FPGA/tb/cosim/rtl_mf_chirp.csv | 0 .../9_2_FPGA/tb/cosim/rtl_mf_dc.csv | 0 .../9_2_FPGA/tb/cosim/rtl_mf_impulse.csv | 0 .../9_2_FPGA/tb/cosim/rtl_mf_tone5.csv | 0 .../tb/cosim/rx_final_doppler_out.csv | 0 .../9_2_FPGA/tb/cosim/scenario_info.txt | 0 .../9_2_FPGA/tb/cosim/validate_mem_files.py | 0 .../9_2_FPGA/tb/ddc_120mhz_output.csv | 0 .../9_2_FPGA/tb/fir_dc_output.csv | 0 .../9_2_FPGA/tb/fir_impulse_output.csv | 0 .../9_2_FPGA/tb/fir_sine_passband.csv | 0 .../9_2_FPGA/tb/gen_mf_golden_ref.py | 2 +- .../9_2_FPGA/tb/golden/golden_doppler.mem | 0 .../9_2_FPGA/tb/mf_golden_out_i_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_out_i_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_out_i_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_out_i_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_out_q_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_out_q_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_out_q_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_out_q_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_i_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_i_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_i_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_i_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_q_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_q_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_q_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_ref_q_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_i_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_i_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_i_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_i_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_q_case1.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_q_case2.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_q_case3.hex | 0 .../9_2_FPGA/tb/mf_golden_sig_q_case4.hex | 0 .../9_2_FPGA/tb/mf_golden_summary.txt | 0 .../9_2_FPGA/tb/mf_pipeline_output.csv | 0 .../9_2_FPGA/tb/nco_120mhz_output.csv | 0 .../9_2_FPGA/tb/nco_1mhz_output.csv | 0 .../9_2_FPGA/tb/nco_freq_switch.csv | 0 .../9_2_FPGA/tb/nco_quadrature.csv | 0 .../9_2_FPGA/tb/radar_system_tb.v | 0 .../9_2_FPGA/tb/tb_ad9484_xsim.v | 0 .../9_2_FPGA/tb/tb_cdc_modules.v | 0 .../9_2_FPGA/tb/tb_cfar_ca.v | 0 .../9_2_FPGA/tb/tb_chirp_contract.v | 0 .../9_2_FPGA/tb/tb_chirp_controller.v | 0 .../9_2_FPGA/tb/tb_cic_decimator.v | 0 .../9_2_FPGA/tb/tb_ddc_400m.v | 0 .../9_2_FPGA/tb/tb_ddc_cosim.v | 0 .../9_2_FPGA/tb/tb_ddc_input_interface.v | 0 .../9_2_FPGA/tb/tb_doppler_cosim.v | 0 .../9_2_FPGA/tb/tb_doppler_realdata.v | 2 +- .../9_2_FPGA/tb/tb_edge_detector.v | 0 .../9_2_FPGA/tb/tb_fft_engine.v | 0 .../9_2_FPGA/tb/tb_fir_lowpass.v | 0 .../9_2_FPGA/tb/tb_fpga_self_test.v | 0 .../9_2_FPGA/tb/tb_freq_matched_filter.v | 0 .../tb/tb_fullchain_mti_cfar_realdata.v | 2 +- .../9_2_FPGA/tb/tb_fullchain_realdata.v | 2 +- .../9_2_FPGA/tb/tb_latency_buffer.v | 0 .../tb/tb_matched_filter_processing_chain.v | 0 .../9_2_FPGA/tb/tb_mf_chain_synth.v | 0 .../9_2_FPGA/tb/tb_mf_cosim.v | 0 .../9_2_FPGA/tb/tb_mti_canceller.v | 0 .../9_2_FPGA/tb/tb_multiseg_cosim.v | 0 .../9_2_FPGA/tb/tb_nco_400m.v | 0 .../9_2_FPGA/tb/tb_nco_xsim.v | 0 .../9_2_FPGA/tb/tb_radar_mode_controller.v | 0 .../9_2_FPGA/tb/tb_radar_receiver_final.v | 0 .../9_2_FPGA/tb/tb_range_bin_decimator.v | 0 .../9_2_FPGA/tb/tb_range_fft_realdata.v | 0 .../9_2_FPGA/tb/tb_rx_gain_control.v | 0 .../9_2_FPGA/tb/tb_system_e2e.v | 0 .../9_2_FPGA/tb/tb_threshold_detector.v | 0 .../9_2_FPGA/tb/tb_usb_data_interface.v | 0 .../9_2_FPGA/usb_data_interface.v | 0 .../9_2_FPGA/usb_data_interface_ft2232h.v | 0 {9_Firmware => firmware}/9_2_FPGA/xfft_16.v | 0 .../9_3_GUI/GUI_PyQt_Map.py | 0 {9_Firmware => firmware}/9_3_GUI/GUI_V5.py | 0 .../9_3_GUI/GUI_V5_Demo.py | 0 {8_Utils => firmware/9_3_GUI}/GUI_V6.gif | Bin {9_Firmware => firmware}/9_3_GUI/GUI_V6.py | 0 .../9_3_GUI/GUI_V65_Tk.py | 0 .../9_3_GUI/GUI_V6_Demo.py | 0 .../9_3_GUI/GUI_V7_PyQt.py | 0 .../9_3_GUI/GUI_versions.txt | 0 .../9_3_GUI/adi_agc_analysis.py | 0 .../9_3_GUI/radar_protocol.py | 0 .../9_3_GUI/requirements_dashboard.txt | 0 .../9_3_GUI/requirements_pyqt_gui.txt | 0 .../9_3_GUI/requirements_v7.txt | 0 .../9_3_GUI/smoke_test.py | 0 .../9_3_GUI/test_GUI_V65_Tk.py | 0 .../9_3_GUI}/test_radar_data.csv | 0 {9_Firmware => firmware}/9_3_GUI/test_v7.py | 0 .../9_3_GUI/v7/__init__.py | 0 .../9_3_GUI/v7/agc_sim.py | 0 .../9_3_GUI/v7/dashboard.py | 0 .../9_3_GUI/v7/hardware.py | 0 .../9_3_GUI/v7/map_widget.py | 0 {9_Firmware => firmware}/9_3_GUI/v7/models.py | 0 .../9_3_GUI/v7/processing.py | 0 {9_Firmware => firmware}/9_3_GUI/v7/replay.py | 0 .../9_3_GUI/v7/software_fpga.py | 2 +- .../9_3_GUI/v7/workers.py | 0 .../tests/cross_layer/.gitignore | 0 .../cross_layer/adar1000_vm_reference.py | 4 +- .../tests/cross_layer/contract_parser.py | 0 .../tests/cross_layer/stm32_settings_stub.cpp | 4 +- .../cross_layer/tb_cross_layer_ft2232h.v | 0 .../cross_layer/test_cross_layer_contract.py | 2 +- .../tools/uart_capture.py | 0 .../application-notes}/UG-290.pdf | Bin .../description}/Project_Description.docx | Bin .../diagrams}/RADAR_V6.drawio | 0 .../diagrams}/RADAR_V6.jpg | Bin .../diagrams}/RADAR_V6_V2.png | Bin {8_Utils => hardware/mechanical}/0044.jpg | Bin .../3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg | Bin .../mechanical}/AERIS-10_RADAR.png | Bin .../mechanical}/Antenna_Array.jpg | Bin .../Eagle_ CAD_Libs/142-0731-211.lbr | 0 .../Eagle_ CAD_Libs/AD9523BCPZ.lbr | 0 .../Eagle_ CAD_Libs/AFII-TC-0015.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/Air_Link.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/CONMCX013.lbr | 0 .../Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr | 0 .../Eagle_ CAD_Libs/My_Library.lbr | 0 .../Eagle_ CAD_Libs/My_Library_2.lbr | 0 .../Eagle_ CAD_Libs/My_Library_RADAR.lbr | 0 .../Eagle_ CAD_Libs/My_Library_SDR.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/NRF905.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/QPA2811.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/SF2321D.lbr | 0 .../Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr | 0 .../Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr | 0 .../Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr | 0 .../Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr | 0 .../Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr | 0 .../mechanical}/Eagle_ CAD_Libs/mmWAVE.lbr | 0 {8_Utils => hardware/mechanical}/GUI.jpg | Bin .../mechanical}/GUI_V6.gif | Bin .../Down_Part_Waveguide.dwg | Bin .../Mechanical_Drawings/Enclosure.bak | Bin .../Mechanical_Drawings/Enclosure.dwg | Bin .../Heat_Sink_Main_Board.dwg | Bin .../Mechanical_Drawings/Heat_Sink_PA.dwg | Bin .../Mechanical_Drawings/RADAR_V1.bak | Bin .../Mechanical_Drawings/RADAR_V1.dwg | Bin .../Mechanical_Drawings/SlipRing.dwg | Bin .../Upper_Part_Waveguide.dwg | Bin .../Mechanical_Drawings/Waveguide.dwg | Bin {8_Utils => hardware/mechanical}/Nawfal.png | Bin {8_Utils => hardware/mechanical}/PCBWAY.jpg | Bin .../mechanical}/Python/CSV_radar.py | 0 .../mechanical}/Python/CSV_radar_2.py | 0 .../mechanical}/Python/FFT_Ramp_Frequency.py | 0 .../mechanical}/Python/Gen_Triangular.py | 0 .../Python/Generic_Ramp_Frequency.py | 0 .../Python/Generic_Triangular_Frequency.py | 0 .../mechanical}/Python/LUT.py | 0 .../mechanical}/Python/RADAR_eq.py | 0 .../mechanical}/Python/Ramp_Frequency.py | 0 .../mechanical}/Python/patch_antenna.py | 0 .../Python/small_test_radar_data.csv | 0 .../mechanical/Python}/test_radar_data.csv | 0 .../mechanical}/RADAR_V6_V2.jpg | Bin .../mechanical}/RADAR_V6_V2.png | Bin .../mechanical}/SplitRing_test.mp4 | Bin ...e3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg | Bin .../power}/Power Management V6.xlsx | Bin .../AAF_openEMS/aaf_simulation.py | 0 .../Antenna/Quartz_Waveguide.py | 0 .../openems_quartz_slotted_wg_10p5GHz.py | 0 .../DAC_ReconstructionFilter/DAC_RLPF.dat | Bin .../DAC_ReconstructionFilter/DAC_RLPF.dpl | 0 .../DAC_ReconstructionFilter/DAC_RLPF.sch | 0 .../Generate_ChirpcsvFile.py | 0 .../DAC_ReconstructionFilter/dac_output.csv | 0 .../multi_ramp_output.csv | 0 .../multi_ramp_stairs.csv | 0 .../DAC_ReconstructionFilter/ramp_output.csv | 0 .../E_plane_Kaiser25dB_like.png | Bin .../rf-simulations}/E_plane_cut.png | Bin .../rf-simulations}/Fencing/Via_fencing.py | 0 .../rf-simulations}/Fencing/Via_fencing2.py | 0 .../Fencing/via_fence_setup_pitch.png | Bin .../Fencing/via_fence_setup_pitch_offset.png | Bin .../H_plane_Kaiser25dB_like.png | Bin .../rf-simulations}/H_plane_cut.png | Bin .../Heatmap_Kaiser25dB_like.png | Bin .../rf-simulations}/IF_BPF/IF_BPF.dat | Bin .../rf-simulations}/IF_BPF/IF_BPF.dpl | 0 .../rf-simulations}/IF_BPF/IF_BPF.sch | 0 .../IF_BPF_Balanced/IF_BPF_Balanced.dat | Bin .../IF_BPF_Balanced/IF_BPF_Balanced.dpl | 0 .../IF_BPF_Balanced/IF_BPF_Balanced.sch | 0 .../IF_BPF_Balanced/multiband_signal.csv | 0 .../IF_BPF_Balanced/six_tone_signal.csv | 0 .../rf-simulations}/Matlab/16_8.m | 0 .../rf-simulations}/Matlab/Antenna16_8.m | 0 .../rf-simulations}/Matlab/Antenna_array.m | 0 .../Matlab/DielectricCatalog.csv | 0 .../Matlab/antenna16_antenna8.m | 0 .../rf-simulations}/Matlab/pattern_data.mat | Bin .../rf-simulations}/QPA2962.dat | Bin .../rf-simulations}/QPA2962.dpl | 0 .../rf-simulations}/QPA2962.sch | 0 .../rf-simulations}/RF switch/Impedance.dat | Bin .../rf-simulations}/RF switch/Impedance.dpl | 0 .../rf-simulations}/RF switch/Impedance.sch | 0 ...R+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p | 0 ...DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p | 0 ...R+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p | 0 ...DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p | 0 .../Sim_BPF_Te_100um/Drawing1.bak | 0 .../Sim_BPF_Te_100um/Drawing1.dxf | 0 .../Gerber-2025-09-21_024138.zip | Bin .../Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb | 0 .../Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl | 0 .../Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro | 0 .../Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch | 0 .../Sim_BPF_Te_100um/Gerber/fp-info-cache | 0 .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat | Bin .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl | 0 .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds | 0 .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite | Bin .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.net | 0 .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb | 0 .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf | Bin .../Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch | 0 .../Sim_BPF_Te_100um/gerber_file.gbr | 0 .../Sim_BPF_Te_100um/qucs2grb_log.txt | 0 .../Slotted_DielectricFilled_Waveguide.m | 0 .../rf-simulations}/Stub_BPF/Stub_BPF.dat | Bin .../rf-simulations}/Stub_BPF/Stub_BPF.net | 0 .../rf-simulations}/Stub_BPF/Stub_BPF.sch | 0 .../rf-simulations}/Stub_BPF_V5.dat | Bin .../rf-simulations}/Stub_BPF_V5.dpl | 0 .../rf-simulations}/Stub_BPF_V5.sch | 0 .../array_pattern_Kaiser25dB_like.py | 0 .../rf-simulations}/array_pattern_heatmap.png | Bin .../rf-simulations}/sim_wg_alumina_32/et | 0 .../rf-simulations}/sim_wg_alumina_32/ht | 0 .../sim_wg_alumina_32/port_it1A | 0 .../sim_wg_alumina_32/port_it1B | 0 .../sim_wg_alumina_32/port_ut1A | 0 .../sim_wg_alumina_32/port_ut1B | 0 .../sim_wg_alumina_32/port_ut1C | 0 .../sim_wg_alumina_32/wg_alumina_32.xml | 0 .../rf-simulations}/sim_wg_alumina_fast/et | 0 .../rf-simulations}/sim_wg_alumina_fast/ht | 0 .../sim_wg_alumina_fast/port_it1A | 0 .../sim_wg_alumina_fast/port_it1B | 0 .../sim_wg_alumina_fast/port_ut1A | 0 .../sim_wg_alumina_fast/port_ut1B | 0 .../sim_wg_alumina_fast/port_ut1C | 0 .../sim_wg_alumina_fast/wg_alumina.xml | 0 .../rf-simulations}/slot_layout_taper32.csv | 0 .../wg_alumina_slotted_openems.m | 0 montecarlo_stats.json | 47 - parts/README.md | 13 + parts/cost.md | 9 + .../datasheets}/60124102122403.pdf | Bin ...MTH801C-20 SMA Broadband Circulator .pdf | Bin .../AD9484/AD9434_AD9484_Schematic.pdf | Bin .../datasheets}/AD9484/AD9484.pdf | Bin ...X_Chain_Gain_Noise_Summary_ABAC_Radar.docx | Bin .../datasheets}/AD9484/UG-290.pdf | Bin .../datasheets}/AD9484/ad8352.pdf | Bin .../datasheets}/AD9708.pdf | Bin .../datasheets}/ADAR1000.pdf | Bin .../datasheets}/ADF4382A/ADF4382A.pdf | Bin .../eval_adf4382a_ug_2185-3392420.pdf | Bin .../datasheets}/ADM7151.pdf | Bin .../datasheets}/AT93C46A.pdf | Bin .../datasheets}/DS_FT2232H.pdf | Bin .../datasheets}/DS_FT232RN.pdf | Bin .../datasheets}/EP4RKU_2b-1858448.pdf | Bin .../FR2-SMA-KFD0405A_2025-08-11.pdf | Bin .../datasheets}/LTC5552f.pdf | Bin .../datasheets}/LTC6419fa.pdf | Bin .../datasheets}/M3SWA2-34DR+.pdf | Bin .../datasheets}/MAX1449-3468915.pdf | 0 ...SM-Integrated Drive GaAs MMIC IQ Mixer.pdf | Bin .../datasheets}/MTX2-143+.pdf | Bin .../datasheets}/PMA2-123LNW+.pdf | Bin .../datasheets}/PMA5_123_3W_2b-3577903.pdf | Bin .../datasheets}/QPA1013D Data Sheet.pdf | Bin .../QPA2962/QPA2962 Data Sheet.pdf | Bin .../QPA2962_SN63_22v1680ma_25C.s2p | 0 .../QPA2962_SN63_22v1680ma_85C.s2p | 0 .../QPA2962_SN63_22v1680ma_n40C.s2p | 0 .../datasheets}/QPM1021 Data Sheet.pdf | Bin ...s RO4003C and RO4350B - Data Sheet (1).pdf | Bin ...nates RO4003C and RO4350B - Data Sheet.pdf | Bin .../datasheets}/SMIQ-5143H+.pdf | Bin .../datasheets}/STUW81300TR.pdf | Bin .../TGA2623_Data_Sheet-1518452.pdf | Bin .../datasheets}/ads7830.pdf | Bin .../datasheets}/adtr1107.pdf | Bin .../attenuator_n_catalog_partition37_en.pdf | Bin .../datasheets}/dac7578.pdf | Bin .../datasheets}/hr2220p601r-10-datasheet.pdf | Bin .../datasheets}/ina241a.pdf | Bin .../datasheets}/lm2663.pdf | Bin .../datasheets}/max20029-max20029d.pdf | Bin .../datasheets}/opa703.pdf | Bin .../datasheets}/tmp35_36_37.pdf | Bin .../datasheets}/tps562201.pdf | Bin .../datasheets}/tps7a8300.pdf | Bin parts/parts-list.csv | 183 + run_simulation.sh | 21 - .../4_4_Board Stack-up/Stack_Hybrid.png | Bin .../Antennas/Patch/4x4/Phased_Array_Ant.brd | 0 .../Antennas/Patch/4x4/Phased_Array_Ant.sch | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#1 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#2 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#3 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#4 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#5 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#6 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#7 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#8 | 0 .../Patch/8x16/Patch_Anetnna_16_8.b#9 | 0 .../Patch/8x16/Patch_Anetnna_16_8.brd | 0 .../Patch/8x16/Patch_Anetnna_16_8.s#1 | 0 .../Patch/8x16/Patch_Anetnna_16_8.s#2 | 0 .../Patch/8x16/Patch_Anetnna_16_8.s#3 | 0 .../Patch/8x16/Patch_Anetnna_16_8.s#4 | 0 .../Patch/8x16/Patch_Anetnna_16_8.sch | 0 .../Antennas/Patch/8x16/place.scr | 0 .../Antennas/Waveguide/DFSWA.dwg | Bin ...ielectric_Filled_Waveguide_Array_Spec.docx | Bin .../Clocks_Freq_Synth_board.brd | 0 .../Clocks_Freq_Synth_board.sch | 0 .../MainBoard/RADAR_Main_Board.brd | 0 .../MainBoard/RADAR_Main_Board.sch | 0 .../PowerAmplifierBoard/RF_PA.brd | 0 .../PowerAmplifierBoard/RF_PA.sch | 0 .../4_6_Schematics/PowerBoard/PowerBoard.brd | 0 .../4_6_Schematics/PowerBoard/PowerBoard.sch | 0 .../4_6_Schematics/Stack_Hybrid.png | Bin .../Gerber_Main_Board/BOM_Main_Board.xlsx | Bin .../Gerber_Main_Board/CPL.xlsx | Bin .../Gerber_Main_Board/RADAR_Main_Board.L1 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L10 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L2 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L3 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L4 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L5 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L6 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L7 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L8 | 0 .../Gerber_Main_Board/RADAR_Main_Board.L9 | 0 .../Gerber_Main_Board/RADAR_Main_Board.bps | 0 .../Gerber_Main_Board/RADAR_Main_Board.bsk | 0 .../Gerber_Main_Board/RADAR_Main_Board.drd | 0 .../Gerber_Main_Board/RADAR_Main_Board.dri | 0 .../Gerber_Main_Board/RADAR_Main_Board.drl | 0 .../Gerber_Main_Board/RADAR_Main_Board.gpi | 0 .../Gerber_Main_Board/RADAR_Main_Board.oln | 0 .../Gerber_Main_Board/RADAR_Main_Board.slk | 0 .../Gerber_Main_Board/RADAR_Main_Board.smb | 0 .../Gerber_Main_Board/RADAR_Main_Board.smt | 0 .../Gerber_Main_Board/RADAR_Main_Board.tps | 0 .../4_7_Production Files/Gerber_PA/BOM.xlsx | Bin .../Gerber_PA/BOM_PA.xlsx | Bin .../4_7_Production Files/Gerber_PA/CPL.xlsx | Bin .../4_7_Production Files/Gerber_PA/RF_PA.L1 | 0 .../4_7_Production Files/Gerber_PA/RF_PA.L2 | 0 .../4_7_Production Files/Gerber_PA/RF_PA.L3 | 0 .../4_7_Production Files/Gerber_PA/RF_PA.L4 | 0 .../4_7_Production Files/Gerber_PA/RF_PA.adb | 0 .../4_7_Production Files/Gerber_PA/RF_PA.adt | 0 .../4_7_Production Files/Gerber_PA/RF_PA.bgl | 0 .../4_7_Production Files/Gerber_PA/RF_PA.bps | 0 .../4_7_Production Files/Gerber_PA/RF_PA.bsk | 0 .../4_7_Production Files/Gerber_PA/RF_PA.drd | 0 .../4_7_Production Files/Gerber_PA/RF_PA.dri | 0 .../4_7_Production Files/Gerber_PA/RF_PA.drl | 0 .../4_7_Production Files/Gerber_PA/RF_PA.fab | 0 .../4_7_Production Files/Gerber_PA/RF_PA.gpi | 0 .../4_7_Production Files/Gerber_PA/RF_PA.oln | 0 .../4_7_Production Files/Gerber_PA/RF_PA.slk | 0 .../4_7_Production Files/Gerber_PA/RF_PA.smb | 0 .../4_7_Production Files/Gerber_PA/RF_PA.smt | 0 .../4_7_Production Files/Gerber_PA/RF_PA.tgl | 0 .../4_7_Production Files/Gerber_PA/RF_PA.tps | 0 .../4_7_Production Files/Gerber_PA/RF_PA_MNB | 0 .../4_7_Production Files/Gerber_PA/RF_PA_MNT | 0 .../BOM_Patch_Antenna.xlsx | Bin .../Gerber_Patch_Antenna/CPL.xlsx | Bin .../Patch_Anetnna_16_8.L1 | 0 .../Patch_Anetnna_16_8.L2 | 0 .../Patch_Anetnna_16_8.L3 | 0 .../Patch_Anetnna_16_8.L4 | 0 .../Patch_Anetnna_16_8.adb | 0 .../Patch_Anetnna_16_8.adt | 0 .../Patch_Anetnna_16_8.bps | 0 .../Patch_Anetnna_16_8.bsk | 0 .../Patch_Anetnna_16_8.drd | 0 .../Patch_Anetnna_16_8.dri | 0 .../Patch_Anetnna_16_8.drl | 0 .../Patch_Anetnna_16_8.gpi | 0 .../Patch_Anetnna_16_8.mnb | 0 .../Patch_Anetnna_16_8.mnt | 0 .../Patch_Anetnna_16_8.oln | 0 .../Patch_Anetnna_16_8.slk | 0 .../Patch_Anetnna_16_8.smb | 0 .../Patch_Anetnna_16_8.smt | 0 .../Patch_Anetnna_16_8.tps | 0 .../Gerber_PowerBoard/BOM.xlsx | Bin .../Gerber_PowerBoard/BOM_Power_Board.xlsx | Bin .../Gerber_PowerBoard/CPL.xlsx | Bin .../Gerber_PowerBoard/PowerBoard.bot | 0 .../Gerber_PowerBoard/PowerBoard.bsk | 0 .../Gerber_PowerBoard/PowerBoard.bsp | 0 .../Gerber_PowerBoard/PowerBoard.csv | 0 .../Gerber_PowerBoard/PowerBoard.drd | 0 .../Gerber_PowerBoard/PowerBoard.dri | 0 .../Gerber_PowerBoard/PowerBoard.drl | 0 .../Gerber_PowerBoard/PowerBoard.gpi | 0 .../Gerber_PowerBoard/PowerBoard.mnb | 0 .../Gerber_PowerBoard/PowerBoard.mnt | 0 .../Gerber_PowerBoard/PowerBoard.oln | 0 .../Gerber_PowerBoard/PowerBoard.slk | 0 .../Gerber_PowerBoard/PowerBoard.smb | 0 .../Gerber_PowerBoard/PowerBoard.smt | 0 .../Gerber_PowerBoard/PowerBoard.top | 0 .../Gerber_PowerBoard/PowerBoard.tsp | 0 .../Gerber_PowerBoard/PowerBoard_CSV_BOM | 0 .../Gerber_freq_synth/BOM_Freq_Synth.xlsx | Bin .../Gerber_freq_synth/CPL.xlsx | Bin .../Clocks_Freq_Synth_board.L1 | 0 .../Clocks_Freq_Synth_board.L2 | 0 .../Clocks_Freq_Synth_board.L3 | 0 .../Clocks_Freq_Synth_board.L4 | 0 .../Clocks_Freq_Synth_board.L5 | 0 .../Clocks_Freq_Synth_board.L6 | 0 .../Clocks_Freq_Synth_board.bps | 0 .../Clocks_Freq_Synth_board.bsk | 0 .../Clocks_Freq_Synth_board.csv | 0 .../Clocks_Freq_Synth_board.drd | 0 .../Clocks_Freq_Synth_board.dri | 0 .../Clocks_Freq_Synth_board.drl | 0 .../Clocks_Freq_Synth_board.gpi | 0 .../Clocks_Freq_Synth_board.mnb | 0 .../Clocks_Freq_Synth_board.mnt | 0 .../Clocks_Freq_Synth_board.oln | 0 .../Clocks_Freq_Synth_board.slk | 0 .../Clocks_Freq_Synth_board.smb | 0 .../Clocks_Freq_Synth_board.smt | 0 .../Clocks_Freq_Synth_board.tps | 0 .../Clocks_Freq_Synth_board_BOM_CSV | 0 .../Clocks_Freq_Synth_board_mnb | 0 .../Clocks_Freq_Synth_board_mnt | 0 ...PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf | 0 simulate_city_defense_radar.py | 241 - simulate_dual_radar_tracking.py | 266 - simulate_interceptor_drones.py | 214 - simulate_three_radar_tracking.py | 204 - simulate_trajectory_precision.py | 240 - {defense_sim_v2 => simulation}/.gitignore | 0 {defense_sim_v2 => simulation}/DEMO_USER.txt | 0 .../PROJECT_SPEC.md | 8 +- {defense_sim_v2 => simulation}/README.md | 14 +- .../deploy/defense-sim-backend.service | 8 +- .../deploy/supabase/compose.yml | 0 .../deploy/supabase/frontend.conf | 0 .../deploy/supabase/migrate.sql | 0 .../deploy/supabase/roles.sql | 0 .../deploy/traefik-defense-sim-v2.yml | 0 .../frontend/.dockerignore | 0 .../frontend/.editorconfig | 0 .../frontend/.env.example | 2 +- .../frontend/.github/FUNDING.yml | 0 .../frontend/.github/workflows/ci.yml | 0 .../frontend/.gitignore | 0 .../frontend/.npmrc | 0 .../frontend/.vscode/extensions.json | 0 .../frontend/.vscode/settings.json | 0 .../frontend/Dockerfile | 0 .../frontend/README.md | 0 .../frontend/components.json | 0 .../frontend/cypress.config.ts | 0 .../frontend/cypress/e2e/auth.spec.ts | 0 .../frontend/cypress/e2e/basic.spec.ts | 0 .../frontend/cypress/tsconfig.json | 0 .../frontend/eslint.config.js | 0 .../frontend/index.html | 0 .../frontend/locales/README.md | 0 .../frontend/locales/en.yml | 0 .../frontend/netlify.toml | 0 .../frontend/package.json | 0 .../frontend/pnpm-lock.yaml | 0 .../frontend/pnpm-workspace.yaml | 0 .../frontend/public/_headers | 0 .../frontend/public/favicon-dark.svg | 0 .../frontend/public/favicon.svg | 0 .../frontend/public/pwa-192x192.png | Bin .../frontend/public/pwa-512x512.png | Bin .../frontend/public/safari-pinned-tab.svg | 0 .../frontend/src/App.vue | 2 +- .../frontend/src/auto-imports.d.ts | 0 .../frontend/src/components.d.ts | 2 + .../frontend/src/components/AppSidebar.vue | 2 +- .../src/components/DarkModeSwitcher.vue | 0 .../src/components/LanguageSwitcher.vue | 0 .../frontend/src/components/README.md | 0 .../src/components/RadarConsolePanel.vue | 196 + .../frontend/src/components/RadarPlot.vue | 111 + .../src/components/SimulationScene.vue | 238 +- .../frontend/src/components/TheInput.vue | 0 .../src/components/ui/accordion/Accordion.vue | 0 .../ui/accordion/AccordionContent.vue | 0 .../components/ui/accordion/AccordionItem.vue | 0 .../ui/accordion/AccordionTrigger.vue | 0 .../src/components/ui/accordion/index.ts | 0 .../ui/alert-dialog/AlertDialog.vue | 0 .../ui/alert-dialog/AlertDialogAction.vue | 0 .../ui/alert-dialog/AlertDialogCancel.vue | 0 .../ui/alert-dialog/AlertDialogContent.vue | 0 .../alert-dialog/AlertDialogDescription.vue | 0 .../ui/alert-dialog/AlertDialogFooter.vue | 0 .../ui/alert-dialog/AlertDialogHeader.vue | 0 .../ui/alert-dialog/AlertDialogTitle.vue | 0 .../ui/alert-dialog/AlertDialogTrigger.vue | 0 .../src/components/ui/alert-dialog/index.ts | 0 .../src/components/ui/alert/Alert.vue | 0 .../components/ui/alert/AlertDescription.vue | 0 .../src/components/ui/alert/AlertTitle.vue | 0 .../frontend/src/components/ui/alert/index.ts | 0 .../ui/aspect-ratio/AspectRatio.vue | 0 .../src/components/ui/aspect-ratio/index.ts | 0 .../src/components/ui/avatar/Avatar.vue | 0 .../components/ui/avatar/AvatarFallback.vue | 0 .../src/components/ui/avatar/AvatarImage.vue | 0 .../src/components/ui/avatar/index.ts | 0 .../src/components/ui/badge/Badge.vue | 0 .../frontend/src/components/ui/badge/index.ts | 0 .../components/ui/breadcrumb/Breadcrumb.vue | 0 .../ui/breadcrumb/BreadcrumbEllipsis.vue | 0 .../ui/breadcrumb/BreadcrumbItem.vue | 0 .../ui/breadcrumb/BreadcrumbLink.vue | 0 .../ui/breadcrumb/BreadcrumbList.vue | 0 .../ui/breadcrumb/BreadcrumbPage.vue | 0 .../ui/breadcrumb/BreadcrumbSeparator.vue | 0 .../src/components/ui/breadcrumb/index.ts | 0 .../ui/button-group/ButtonGroup.vue | 0 .../ui/button-group/ButtonGroupSeparator.vue | 0 .../ui/button-group/ButtonGroupText.vue | 0 .../src/components/ui/button-group/index.ts | 0 .../src/components/ui/button/Button.vue | 0 .../src/components/ui/button/index.ts | 0 .../src/components/ui/calendar/Calendar.vue | 0 .../components/ui/calendar/CalendarCell.vue | 0 .../ui/calendar/CalendarCellTrigger.vue | 0 .../components/ui/calendar/CalendarGrid.vue | 0 .../ui/calendar/CalendarGridBody.vue | 0 .../ui/calendar/CalendarGridHead.vue | 0 .../ui/calendar/CalendarGridRow.vue | 0 .../ui/calendar/CalendarHeadCell.vue | 0 .../components/ui/calendar/CalendarHeader.vue | 0 .../ui/calendar/CalendarHeading.vue | 0 .../ui/calendar/CalendarNextButton.vue | 0 .../ui/calendar/CalendarPrevButton.vue | 0 .../src/components/ui/calendar/index.ts | 0 .../frontend/src/components/ui/card/Card.vue | 0 .../src/components/ui/card/CardContent.vue | 0 .../components/ui/card/CardDescription.vue | 0 .../src/components/ui/card/CardFooter.vue | 0 .../src/components/ui/card/CardHeader.vue | 0 .../src/components/ui/card/CardTitle.vue | 0 .../frontend/src/components/ui/card/index.ts | 0 .../src/components/ui/carousel/Carousel.vue | 0 .../ui/carousel/CarouselContent.vue | 0 .../components/ui/carousel/CarouselItem.vue | 0 .../components/ui/carousel/CarouselNext.vue | 0 .../ui/carousel/CarouselPrevious.vue | 0 .../src/components/ui/carousel/index.ts | 0 .../src/components/ui/carousel/interface.ts | 0 .../src/components/ui/carousel/useCarousel.ts | 0 .../components/ui/chart/ChartCrosshair.vue | 0 .../src/components/ui/chart/ChartLegend.vue | 0 .../ui/chart/ChartSingleTooltip.vue | 0 .../src/components/ui/chart/ChartTooltip.vue | 0 .../frontend/src/components/ui/chart/index.ts | 0 .../src/components/ui/chart/interface.ts | 0 .../components/ui/chart/mountChartTooltip.ts | 0 .../src/components/ui/checkbox/Checkbox.vue | 0 .../src/components/ui/checkbox/index.ts | 0 .../components/ui/collapsible/Collapsible.vue | 0 .../ui/collapsible/CollapsibleContent.vue | 0 .../ui/collapsible/CollapsibleTrigger.vue | 0 .../src/components/ui/collapsible/index.ts | 0 .../src/components/ui/combobox/Combobox.vue | 0 .../components/ui/combobox/ComboboxAnchor.vue | 0 .../components/ui/combobox/ComboboxEmpty.vue | 0 .../components/ui/combobox/ComboboxGroup.vue | 0 .../components/ui/combobox/ComboboxInput.vue | 0 .../components/ui/combobox/ComboboxItem.vue | 0 .../components/ui/combobox/ComboboxList.vue | 0 .../ui/combobox/ComboboxSeparator.vue | 0 .../ui/combobox/ComboboxTrigger.vue | 0 .../src/components/ui/combobox/index.ts | 0 .../src/components/ui/command/Command.vue | 0 .../components/ui/command/CommandDialog.vue | 0 .../components/ui/command/CommandEmpty.vue | 0 .../components/ui/command/CommandGroup.vue | 0 .../components/ui/command/CommandInput.vue | 0 .../src/components/ui/command/CommandItem.vue | 0 .../src/components/ui/command/CommandList.vue | 0 .../ui/command/CommandSeparator.vue | 0 .../components/ui/command/CommandShortcut.vue | 0 .../src/components/ui/command/index.ts | 0 .../ui/context-menu/ContextMenu.vue | 0 .../context-menu/ContextMenuCheckboxItem.vue | 0 .../ui/context-menu/ContextMenuContent.vue | 0 .../ui/context-menu/ContextMenuGroup.vue | 0 .../ui/context-menu/ContextMenuItem.vue | 0 .../ui/context-menu/ContextMenuLabel.vue | 0 .../ui/context-menu/ContextMenuPortal.vue | 0 .../ui/context-menu/ContextMenuRadioGroup.vue | 0 .../ui/context-menu/ContextMenuRadioItem.vue | 0 .../ui/context-menu/ContextMenuSeparator.vue | 0 .../ui/context-menu/ContextMenuShortcut.vue | 0 .../ui/context-menu/ContextMenuSub.vue | 0 .../ui/context-menu/ContextMenuSubContent.vue | 0 .../ui/context-menu/ContextMenuSubTrigger.vue | 0 .../ui/context-menu/ContextMenuTrigger.vue | 0 .../src/components/ui/context-menu/index.ts | 0 .../src/components/ui/dialog/Dialog.vue | 0 .../src/components/ui/dialog/DialogClose.vue | 0 .../components/ui/dialog/DialogContent.vue | 0 .../ui/dialog/DialogDescription.vue | 0 .../src/components/ui/dialog/DialogFooter.vue | 0 .../src/components/ui/dialog/DialogHeader.vue | 0 .../ui/dialog/DialogScrollContent.vue | 0 .../src/components/ui/dialog/DialogTitle.vue | 0 .../components/ui/dialog/DialogTrigger.vue | 0 .../src/components/ui/dialog/index.ts | 0 .../src/components/ui/drawer/Drawer.vue | 0 .../components/ui/drawer/DrawerContent.vue | 0 .../ui/drawer/DrawerDescription.vue | 0 .../src/components/ui/drawer/DrawerFooter.vue | 0 .../src/components/ui/drawer/DrawerHeader.vue | 0 .../components/ui/drawer/DrawerOverlay.vue | 0 .../src/components/ui/drawer/DrawerTitle.vue | 0 .../src/components/ui/drawer/index.ts | 0 .../ui/dropdown-menu/DropdownMenu.vue | 0 .../DropdownMenuCheckboxItem.vue | 0 .../ui/dropdown-menu/DropdownMenuContent.vue | 0 .../ui/dropdown-menu/DropdownMenuGroup.vue | 0 .../ui/dropdown-menu/DropdownMenuItem.vue | 0 .../ui/dropdown-menu/DropdownMenuLabel.vue | 0 .../dropdown-menu/DropdownMenuRadioGroup.vue | 0 .../dropdown-menu/DropdownMenuRadioItem.vue | 0 .../dropdown-menu/DropdownMenuSeparator.vue | 0 .../ui/dropdown-menu/DropdownMenuShortcut.vue | 0 .../ui/dropdown-menu/DropdownMenuSub.vue | 0 .../dropdown-menu/DropdownMenuSubContent.vue | 0 .../dropdown-menu/DropdownMenuSubTrigger.vue | 0 .../ui/dropdown-menu/DropdownMenuTrigger.vue | 0 .../src/components/ui/dropdown-menu/index.ts | 0 .../src/components/ui/empty/Empty.vue | 0 .../src/components/ui/empty/EmptyContent.vue | 0 .../components/ui/empty/EmptyDescription.vue | 0 .../src/components/ui/empty/EmptyHeader.vue | 0 .../src/components/ui/empty/EmptyMedia.vue | 0 .../src/components/ui/empty/EmptyTitle.vue | 0 .../frontend/src/components/ui/empty/index.ts | 0 .../src/components/ui/field/Field.vue | 0 .../src/components/ui/field/FieldContent.vue | 0 .../components/ui/field/FieldDescription.vue | 0 .../src/components/ui/field/FieldError.vue | 0 .../src/components/ui/field/FieldGroup.vue | 0 .../src/components/ui/field/FieldLabel.vue | 0 .../src/components/ui/field/FieldLegend.vue | 0 .../components/ui/field/FieldSeparator.vue | 0 .../src/components/ui/field/FieldSet.vue | 0 .../src/components/ui/field/FieldTitle.vue | 0 .../frontend/src/components/ui/field/index.ts | 0 .../src/components/ui/form/FormControl.vue | 0 .../components/ui/form/FormDescription.vue | 0 .../src/components/ui/form/FormItem.vue | 0 .../src/components/ui/form/FormLabel.vue | 0 .../src/components/ui/form/FormMessage.vue | 0 .../frontend/src/components/ui/form/index.ts | 0 .../src/components/ui/form/injectionKeys.ts | 0 .../src/components/ui/form/useFormField.ts | 0 .../components/ui/hover-card/HoverCard.vue | 0 .../ui/hover-card/HoverCardContent.vue | 0 .../ui/hover-card/HoverCardTrigger.vue | 0 .../src/components/ui/hover-card/index.ts | 0 .../components/ui/input-group/InputGroup.vue | 0 .../ui/input-group/InputGroupAddon.vue | 0 .../ui/input-group/InputGroupButton.vue | 0 .../ui/input-group/InputGroupInput.vue | 0 .../ui/input-group/InputGroupText.vue | 0 .../ui/input-group/InputGroupTextarea.vue | 0 .../src/components/ui/input-group/index.ts | 0 .../src/components/ui/input/Input.vue | 0 .../frontend/src/components/ui/input/index.ts | 0 .../frontend/src/components/ui/item/Item.vue | 0 .../src/components/ui/item/ItemActions.vue | 0 .../src/components/ui/item/ItemContent.vue | 0 .../components/ui/item/ItemDescription.vue | 0 .../src/components/ui/item/ItemFooter.vue | 0 .../src/components/ui/item/ItemGroup.vue | 0 .../src/components/ui/item/ItemHeader.vue | 0 .../src/components/ui/item/ItemMedia.vue | 0 .../src/components/ui/item/ItemSeparator.vue | 0 .../src/components/ui/item/ItemTitle.vue | 0 .../frontend/src/components/ui/item/index.ts | 0 .../frontend/src/components/ui/kbd/Kbd.vue | 0 .../src/components/ui/kbd/KbdGroup.vue | 0 .../frontend/src/components/ui/kbd/index.ts | 0 .../src/components/ui/label/Label.vue | 0 .../frontend/src/components/ui/label/index.ts | 0 .../src/components/ui/menubar/Menubar.vue | 0 .../ui/menubar/MenubarCheckboxItem.vue | 0 .../components/ui/menubar/MenubarContent.vue | 0 .../components/ui/menubar/MenubarGroup.vue | 0 .../src/components/ui/menubar/MenubarItem.vue | 0 .../components/ui/menubar/MenubarLabel.vue | 0 .../src/components/ui/menubar/MenubarMenu.vue | 0 .../ui/menubar/MenubarRadioGroup.vue | 0 .../ui/menubar/MenubarRadioItem.vue | 0 .../ui/menubar/MenubarSeparator.vue | 0 .../components/ui/menubar/MenubarShortcut.vue | 0 .../src/components/ui/menubar/MenubarSub.vue | 0 .../ui/menubar/MenubarSubContent.vue | 0 .../ui/menubar/MenubarSubTrigger.vue | 0 .../components/ui/menubar/MenubarTrigger.vue | 0 .../src/components/ui/menubar/index.ts | 0 .../ui/navigation-menu/NavigationMenu.vue | 0 .../navigation-menu/NavigationMenuContent.vue | 0 .../NavigationMenuIndicator.vue | 0 .../ui/navigation-menu/NavigationMenuItem.vue | 0 .../ui/navigation-menu/NavigationMenuLink.vue | 0 .../ui/navigation-menu/NavigationMenuList.vue | 0 .../navigation-menu/NavigationMenuTrigger.vue | 0 .../NavigationMenuViewport.vue | 0 .../components/ui/navigation-menu/index.ts | 0 .../ui/number-field/NumberField.vue | 0 .../ui/number-field/NumberFieldContent.vue | 0 .../ui/number-field/NumberFieldDecrement.vue | 0 .../ui/number-field/NumberFieldIncrement.vue | 0 .../ui/number-field/NumberFieldInput.vue | 0 .../src/components/ui/number-field/index.ts | 0 .../components/ui/pagination/Pagination.vue | 0 .../ui/pagination/PaginationContent.vue | 0 .../ui/pagination/PaginationEllipsis.vue | 0 .../ui/pagination/PaginationFirst.vue | 0 .../ui/pagination/PaginationItem.vue | 0 .../ui/pagination/PaginationLast.vue | 0 .../ui/pagination/PaginationNext.vue | 0 .../ui/pagination/PaginationPrevious.vue | 0 .../src/components/ui/pagination/index.ts | 0 .../src/components/ui/pin-input/PinInput.vue | 0 .../components/ui/pin-input/PinInputGroup.vue | 0 .../ui/pin-input/PinInputSeparator.vue | 0 .../components/ui/pin-input/PinInputSlot.vue | 0 .../src/components/ui/pin-input/index.ts | 0 .../src/components/ui/popover/Popover.vue | 0 .../components/ui/popover/PopoverContent.vue | 0 .../components/ui/popover/PopoverTrigger.vue | 0 .../src/components/ui/popover/index.ts | 0 .../src/components/ui/progress/Progress.vue | 0 .../src/components/ui/progress/index.ts | 0 .../components/ui/radio-group/RadioGroup.vue | 0 .../ui/radio-group/RadioGroupItem.vue | 0 .../src/components/ui/radio-group/index.ts | 0 .../ui/range-calendar/RangeCalendar.vue | 0 .../ui/range-calendar/RangeCalendarCell.vue | 0 .../RangeCalendarCellTrigger.vue | 0 .../ui/range-calendar/RangeCalendarGrid.vue | 0 .../range-calendar/RangeCalendarGridBody.vue | 0 .../range-calendar/RangeCalendarGridHead.vue | 0 .../range-calendar/RangeCalendarGridRow.vue | 0 .../range-calendar/RangeCalendarHeadCell.vue | 0 .../ui/range-calendar/RangeCalendarHeader.vue | 0 .../range-calendar/RangeCalendarHeading.vue | 0 .../RangeCalendarNextButton.vue | 0 .../RangeCalendarPrevButton.vue | 0 .../src/components/ui/range-calendar/index.ts | 0 .../ui/resizable/ResizableHandle.vue | 0 .../ui/resizable/ResizablePanelGroup.vue | 0 .../src/components/ui/resizable/index.ts | 0 .../components/ui/scroll-area/ScrollArea.vue | 0 .../components/ui/scroll-area/ScrollBar.vue | 0 .../src/components/ui/scroll-area/index.ts | 0 .../src/components/ui/select/Select.vue | 0 .../components/ui/select/SelectContent.vue | 0 .../src/components/ui/select/SelectGroup.vue | 0 .../src/components/ui/select/SelectItem.vue | 0 .../components/ui/select/SelectItemText.vue | 0 .../src/components/ui/select/SelectLabel.vue | 0 .../ui/select/SelectScrollDownButton.vue | 0 .../ui/select/SelectScrollUpButton.vue | 0 .../components/ui/select/SelectSeparator.vue | 0 .../components/ui/select/SelectTrigger.vue | 0 .../src/components/ui/select/SelectValue.vue | 0 .../src/components/ui/select/index.ts | 0 .../src/components/ui/separator/Separator.vue | 0 .../src/components/ui/separator/index.ts | 0 .../src/components/ui/sheet/Sheet.vue | 0 .../src/components/ui/sheet/SheetClose.vue | 0 .../src/components/ui/sheet/SheetContent.vue | 0 .../components/ui/sheet/SheetDescription.vue | 0 .../src/components/ui/sheet/SheetFooter.vue | 0 .../src/components/ui/sheet/SheetHeader.vue | 0 .../src/components/ui/sheet/SheetTitle.vue | 0 .../src/components/ui/sheet/SheetTrigger.vue | 0 .../frontend/src/components/ui/sheet/index.ts | 0 .../src/components/ui/sidebar/Sidebar.vue | 0 .../components/ui/sidebar/SidebarContent.vue | 0 .../components/ui/sidebar/SidebarFooter.vue | 0 .../components/ui/sidebar/SidebarGroup.vue | 0 .../ui/sidebar/SidebarGroupAction.vue | 0 .../ui/sidebar/SidebarGroupContent.vue | 0 .../ui/sidebar/SidebarGroupLabel.vue | 0 .../components/ui/sidebar/SidebarHeader.vue | 0 .../components/ui/sidebar/SidebarInput.vue | 0 .../components/ui/sidebar/SidebarInset.vue | 0 .../src/components/ui/sidebar/SidebarMenu.vue | 0 .../ui/sidebar/SidebarMenuAction.vue | 0 .../ui/sidebar/SidebarMenuBadge.vue | 0 .../ui/sidebar/SidebarMenuButton.vue | 0 .../ui/sidebar/SidebarMenuButtonChild.vue | 0 .../components/ui/sidebar/SidebarMenuItem.vue | 0 .../ui/sidebar/SidebarMenuSkeleton.vue | 0 .../components/ui/sidebar/SidebarMenuSub.vue | 0 .../ui/sidebar/SidebarMenuSubButton.vue | 0 .../ui/sidebar/SidebarMenuSubItem.vue | 0 .../components/ui/sidebar/SidebarProvider.vue | 0 .../src/components/ui/sidebar/SidebarRail.vue | 0 .../ui/sidebar/SidebarSeparator.vue | 0 .../components/ui/sidebar/SidebarTrigger.vue | 0 .../src/components/ui/sidebar/index.ts | 0 .../src/components/ui/sidebar/utils.ts | 0 .../src/components/ui/skeleton/Skeleton.vue | 0 .../src/components/ui/skeleton/index.ts | 0 .../src/components/ui/slider/Slider.vue | 0 .../src/components/ui/slider/index.ts | 0 .../src/components/ui/sonner/Sonner.vue | 0 .../src/components/ui/sonner/index.ts | 0 .../src/components/ui/spinner/Spinner.vue | 0 .../src/components/ui/spinner/index.ts | 0 .../src/components/ui/stepper/Stepper.vue | 0 .../ui/stepper/StepperDescription.vue | 0 .../ui/stepper/StepperIndicator.vue | 0 .../src/components/ui/stepper/StepperItem.vue | 0 .../ui/stepper/StepperSeparator.vue | 0 .../components/ui/stepper/StepperTitle.vue | 0 .../components/ui/stepper/StepperTrigger.vue | 0 .../src/components/ui/stepper/index.ts | 0 .../src/components/ui/switch/Switch.vue | 0 .../src/components/ui/switch/index.ts | 0 .../src/components/ui/table/Table.vue | 0 .../src/components/ui/table/TableBody.vue | 0 .../src/components/ui/table/TableCaption.vue | 0 .../src/components/ui/table/TableCell.vue | 0 .../src/components/ui/table/TableEmpty.vue | 0 .../src/components/ui/table/TableFooter.vue | 0 .../src/components/ui/table/TableHead.vue | 0 .../src/components/ui/table/TableHeader.vue | 0 .../src/components/ui/table/TableRow.vue | 0 .../frontend/src/components/ui/table/index.ts | 0 .../frontend/src/components/ui/tabs/Tabs.vue | 0 .../src/components/ui/tabs/TabsContent.vue | 0 .../src/components/ui/tabs/TabsList.vue | 0 .../src/components/ui/tabs/TabsTrigger.vue | 0 .../frontend/src/components/ui/tabs/index.ts | 0 .../components/ui/tags-input/TagsInput.vue | 0 .../ui/tags-input/TagsInputInput.vue | 0 .../ui/tags-input/TagsInputItem.vue | 0 .../ui/tags-input/TagsInputItemDelete.vue | 0 .../ui/tags-input/TagsInputItemText.vue | 0 .../src/components/ui/tags-input/index.ts | 0 .../src/components/ui/textarea/Textarea.vue | 0 .../src/components/ui/textarea/index.ts | 0 .../ui/toggle-group/ToggleGroup.vue | 0 .../ui/toggle-group/ToggleGroupItem.vue | 0 .../src/components/ui/toggle-group/index.ts | 0 .../src/components/ui/toggle/Toggle.vue | 0 .../src/components/ui/toggle/index.ts | 0 .../src/components/ui/tooltip/Tooltip.vue | 0 .../components/ui/tooltip/TooltipContent.vue | 0 .../components/ui/tooltip/TooltipProvider.vue | 0 .../components/ui/tooltip/TooltipTrigger.vue | 0 .../src/components/ui/tooltip/index.ts | 0 .../frontend/src/composables/dark.ts | 0 .../frontend/src/composables/useAuth.ts | 0 .../frontend/src/composables/useLogout.ts | 0 .../src/composables/useSimulationSocket.ts | 74 +- .../frontend/src/config.ts | 2 +- .../frontend/src/devtools/I18nAudit.vue | 0 .../frontend/src/devtools/useI18nAudit.ts | 0 .../frontend/src/layouts/404.vue | 0 .../frontend/src/layouts/README.md | 0 .../frontend/src/layouts/default.vue | 0 .../frontend/src/layouts/login.vue | 0 .../frontend/src/layouts/with-sidebar.vue | 0 .../frontend/src/lib/auth/authErrorHandler.ts | 0 .../src/lib/auth/authReservedPaths.ts | 0 .../frontend/src/lib/auth/inviteRedirect.ts | 0 .../frontend/src/lib/i18n-audit/index.ts | 0 .../frontend/src/lib/i18n-audit/lmstudio.ts | 0 .../frontend/src/lib/i18n-audit/scanner.ts | 0 .../frontend/src/lib/simulationRuns.ts | 0 .../frontend/src/lib/supabaseClient.ts | 0 .../frontend/src/lib/ui-locale-prefs.ts | 0 .../frontend/src/lib/utils.ts | 0 .../frontend/src/main.ts | 0 .../frontend/src/modules/README.md | 0 .../frontend/src/modules/auth.ts | 0 .../frontend/src/modules/dev-i18n-audit.ts | 0 .../frontend/src/modules/i18n.ts | 0 .../frontend/src/modules/nprogress.ts | 0 .../frontend/src/modules/pinia.ts | 0 .../frontend/src/modules/pwa.ts | 0 .../frontend/src/modules/router-auth.ts | 0 .../frontend/src/pages/README.md | 0 .../frontend/src/pages/[...all].vue | 0 .../frontend/src/pages/index.vue | 95 +- .../frontend/src/pages/login.vue | 4 +- .../frontend/src/route-map.d.ts | 0 .../frontend/src/shims.d.ts | 0 .../frontend/src/stores/adminAccess.ts | 0 .../frontend/src/stores/auth.ts | 0 .../frontend/src/styles/main.css | 0 .../frontend/src/styles/markdown.css | 0 .../frontend/src/types.ts | 0 .../frontend/src/types/database.ts | 0 simulation/frontend/src/types/simulation.ts | 126 + .../frontend/src/utils/cldrPluralRules.ts | 0 .../20260930000000_simulation_runs.sql | 0 .../test/__snapshots__/component.test.ts.snap | 0 .../frontend/test/auth.test.ts | 0 .../frontend/test/basic.test.ts | 0 .../frontend/test/component.test.ts | 0 .../frontend/tsconfig.json | 0 .../frontend/uno.config.ts | 0 .../frontend/vite.config.ts | 4 +- {defense_sim_v2 => simulation}/latest_goal.md | 9 +- .../physics_auditing_review_and_gaps.md | 9 +- {defense_sim_v2 => simulation}/prompt.txt | 0 {defense_sim_v2 => simulation}/pyproject.toml | 7 +- simulation/radar_gui_port.md | 42 + .../rebuild_restart.sh | 0 .../scripts/bootstrap_auth.py | 0 .../scripts/create_demo_user.py | 0 simulation/src/defense_sim/__init__.py | 3 + .../src/defense_sim/cli.py | 0 .../src/defense_sim/entities/__init__.py | 0 simulation/src/defense_sim/entities/drone.py | 675 + .../src/defense_sim/entities/projectile.py | 0 .../src/defense_sim/guidance/__init__.py | 0 .../src/defense_sim/guidance/activation.py | 0 simulation/src/defense_sim/guidance/ascent.py | 51 + .../src/defense_sim/guidance/trajectory.py | 535 + .../src/defense_sim/physics/__init__.py | 0 .../src/defense_sim/physics/atmosphere.py | 0 .../src/defense_sim/physics/environment.py | 0 .../src/defense_sim/physics/events.py | 0 .../src/defense_sim/physics/flight.py | 0 .../src/defense_sim/physics/integrator.py | 27 +- .../src/defense_sim/physics/reference.py | 0 .../src/defense_sim/physics/turbulence.py | 0 .../src/defense_sim/physics/validation.py | 0 simulation/src/defense_sim/radar/__init__.py | 1 + simulation/src/defense_sim/radar/console.py | 210 + .../radar/data/plfm_gui_samples.csv | 16385 ++++++++++++++++ .../radar/data/plfm_gui_samples.iq.xz | Bin 0 -> 24100 bytes .../src/defense_sim/radar/replay_data.py | 58 + simulation/src/defense_sim/radar/v6_demo.py | 203 + .../src/defense_sim/sensors/__init__.py | 0 simulation/src/defense_sim/sensors/devices.py | 360 + .../src/defense_sim/sensors/models.py | 0 .../src/defense_sim/sensors/signal_chain.py | 437 + .../src/defense_sim/sensors/tracking.py | 58 +- .../src/defense_sim/server/__init__.py | 0 .../src/defense_sim/server/auth.py | 0 .../src/defense_sim/server/events.py | 0 .../src/defense_sim/server/socketio_server.py | 111 +- .../src/defense_sim/simulation/__init__.py | 0 .../src/defense_sim/simulation/engine.py | 1910 ++ .../src/defense_sim/simulation/presets.py | 0 .../src/defense_sim/simulation/scenarios.py | 33 +- .../src/defense_sim/statistics/__init__.py | 0 .../src/defense_sim/statistics/metrics.py | 0 .../src/defense_sim/statistics/monte_carlo.py | 0 .../tests/test_ascent.py | 20 +- simulation/tests/test_audit_regressions.py | 745 + .../tests/test_auth.py | 0 .../tests/test_flight_adapters.py | 0 .../tests/test_physics.py | 0 .../tests/test_presets.py | 0 simulation/tests/test_radar_console.py | 216 + simulation/tests/test_radar_measurements.py | 266 + .../tests/test_server_runtime.py | 0 simulation/tests/test_standby_and_trails.py | 149 + simulation/tools/export_replay_iq.py | 45 + simulation/tools/probe_signal_chain.py | 120 + test_defense_sim.py | 276 - 1439 files changed, 23822 insertions(+), 6571 deletions(-) delete mode 100644 DEFENSE_SIMULATION.md delete mode 100644 Licence delete mode 100644 debug2.js delete mode 100644 debug_sim.js delete mode 100644 defense_sim.html delete mode 100644 defense_sim.py delete mode 100644 defense_sim_v2/frontend/LICENSE delete mode 100644 defense_sim_v2/frontend/src/types/simulation.ts delete mode 100644 defense_sim_v2/src/defense_sim/__init__.py delete mode 100644 defense_sim_v2/src/defense_sim/entities/drone.py delete mode 100644 defense_sim_v2/src/defense_sim/guidance/ascent.py delete mode 100644 defense_sim_v2/src/defense_sim/guidance/trajectory.py delete mode 100644 defense_sim_v2/src/defense_sim/sensors/devices.py delete mode 100644 defense_sim_v2/src/defense_sim/simulation/engine.py delete mode 100644 defense_sim_v2/tests/test_audit_regressions.py delete mode 100644 defense_sim_v2/tests/test_standby_and_trails.py delete mode 100644 dual_radar_tracking_results.png rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_AGC.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_AGC.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.cpp (97%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.H (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DAC5578.H (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPSPlus.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_types.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod_private.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/jesd204.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_ain.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_aout.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_axi_io.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_delay.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_error.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_flash.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_font_8x8.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_init.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_print_log.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_rtc.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_sin_lut.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_units.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.H (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_hal.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_conf.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/sysmem.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/system_stm32f7xx.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/.gitignore (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/Makefile (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/ad_driver_mock.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/ad_driver_mock.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/adf4382.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/adf4382a_manager.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/diag_log.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/main.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/no_os_delay.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/no_os_spi.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/no_os_units.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/no_os_util.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/platform_noos_stm32.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/stm32_spi.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/shims/stm32f7xx_hal.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/stm32_hal_mock.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/stm32_hal_mock.h (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_agc_outer_loop.cpp (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug10_spi_cs_not_toggled.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug11_platform_spi_transmit_only.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug12_pa_cal_loop_inverted.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug13_dac2_adc_buffer_mismatch.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug14_diag_section_args.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug15_htim3_dangling_extern.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug1_timed_sync_init_ordering.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug2_ad9523_double_setup.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug3_timed_sync_noop.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug4_phase_shift_before_check.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug5_fine_phase_gpio_only.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug6_timer_variable_collision.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug7_gpio_pin_conflict.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c (96%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_bug9_platform_ops_null.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_emergency_state_ordering.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_emergency_stop_rails.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_health_watchdog_cold_start.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_idq_periodic_reread.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_iwdg_config.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_overtemp_emergency_stop.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_gap3_temperature_max.c (100%) rename {9_Firmware => firmware}/9_1_Microcontroller/tests/test_um982_gps.c (100%) rename {9_Firmware => firmware}/9_2_FPGA/.gitignore (100%) rename {9_Firmware => firmware}/9_2_FPGA/ad9484_interface_400m.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/adc_clk_mmcm.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/adc_clk_mmcm_integration.md (100%) rename {9_Firmware => firmware}/9_2_FPGA/cdc_modules.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/cfar_ca.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/chirp_memory_loader_param.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/cic_decimator_4x_enhanced.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/README.md (99%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/adc_clk_mmcm.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/debug_ila.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/te0712_te0701_minimal.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/te0713_te0701_minimal.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/xc7a200t_fbg484.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/constraints/xc7a50t_ftg256.xdc (100%) rename {9_Firmware => firmware}/9_2_FPGA/dac_interface_single.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/ddc_400m.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/ddc_input_interface.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/doppler_processor.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/edge_detector.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/fft_engine.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/fft_twiddle_1024.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/fft_twiddle_16.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/fir_lowpass.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_adc.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_adc.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_handshake.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_handshake.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_handshake_cover.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_single_bit.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_cdc_single_bit.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_doppler_processor.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_doppler_processor.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_radar_mode_controller.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_radar_mode_controller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_range_bin_decimator.sby (100%) rename {9_Firmware => firmware}/9_2_FPGA/formal/fv_range_bin_decimator.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/fpga_self_test.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/frequency_matched_filter.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/latency_buffer.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_lut.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg0_i.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg0_q.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg1_i.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg1_q.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg2_i.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg2_q.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg3_i.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/long_chirp_seg3_q.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/matched_filter_multi_segment.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/matched_filter_processing_chain.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/mti_canceller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/nco_400m_enhanced.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/plfm_chirp_controller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_mode_controller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_receiver_final.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_system_top.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_system_top_50t.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_system_top_te0712_dev.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_system_top_te0713_dev.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/radar_transmitter.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/range_bin_decimator.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/run_regression.sh (100%) rename {9_Firmware => firmware}/9_2_FPGA/rx_gain_control.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/200t/build_200t.tcl (99%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/50t/build_50t.tcl (99%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/te0712/build_te0712_dev.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/te0713/build_te0713_dev.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/te0713/build_te0713_umft601x_dev.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/utils/ila_capture.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/utils/insert_ila_probes.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/utils/program_fpga.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/scripts/utils/run_cdc_and_netlist.tcl (100%) rename {9_Firmware => firmware}/9_2_FPGA/short_chirp_i.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/short_chirp_q.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/ad9484_interface_400m_stub.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cic_dc_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cic_impulse_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cic_sine_passband.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/adc_dc.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/adc_multi_target.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/adc_noise_only.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/adc_sine_1mhz.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/adc_single_target.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/bb_mf_test_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/bb_mf_test_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_dc.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_doppler.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_mf.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_mf_chirp.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_mf_dc.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_mf_impulse.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_mf_tone5.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_multi_target.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_noise_only.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_sine_1mhz.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/compare_single_target.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_moving.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_moving.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_input_moving.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_input_stationary.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/doppler_input_two_targets.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/fpga_model.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/gen_chirp_mem.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/gen_doppler_golden.py (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/gen_multiseg_golden.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_dc.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_i_chirp.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_i_impulse.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_i_tone5.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_impulse.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_q_chirp.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_q_impulse.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_q_tone5.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_dc_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_dc_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_dc_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_dc_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg0_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg0_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg1_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg1_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg2_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg2_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg3_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_golden_seg3_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_input_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_input_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_golden.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_golden_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_golden_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_input_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_input_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/multiseg_short_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/radar_scene.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/golden_reference.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md (98%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/adc_chirp0.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/chirp0_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/chirp0_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/detection_mag.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/detections.txt (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_input_realdata.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_det.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_detections.txt (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_flags.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detection_mag.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detections.txt (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_packed.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_packed.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/fullchain_range_input.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_i.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_q.npy (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/ref_chirp_i.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/ref_chirp_q.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_bb_dc.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_bb_single_target.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_mf_chirp.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_mf_dc.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_mf_impulse.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rtl_mf_tone5.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/rx_final_doppler_out.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/scenario_info.txt (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/cosim/validate_mem_files.py (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/ddc_120mhz_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/fir_dc_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/fir_impulse_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/fir_sine_passband.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/gen_mf_golden_ref.py (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/golden/golden_doppler.mem (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_i_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_i_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_i_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_i_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_q_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_q_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_q_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_out_q_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_i_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_i_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_i_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_i_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_q_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_q_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_q_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_ref_q_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_i_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_i_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_i_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_i_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_q_case1.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_q_case2.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_q_case3.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_sig_q_case4.hex (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_golden_summary.txt (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/mf_pipeline_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/nco_120mhz_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/nco_1mhz_output.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/nco_freq_switch.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/nco_quadrature.csv (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/radar_system_tb.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_ad9484_xsim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_cdc_modules.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_cfar_ca.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_chirp_contract.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_chirp_controller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_cic_decimator.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_ddc_400m.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_ddc_cosim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_ddc_input_interface.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_doppler_cosim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_doppler_realdata.v (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_edge_detector.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_fft_engine.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_fir_lowpass.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_fpga_self_test.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_freq_matched_filter.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_fullchain_realdata.v (99%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_latency_buffer.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_matched_filter_processing_chain.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_mf_chain_synth.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_mf_cosim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_mti_canceller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_multiseg_cosim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_nco_400m.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_nco_xsim.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_radar_mode_controller.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_radar_receiver_final.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_range_bin_decimator.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_range_fft_realdata.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_rx_gain_control.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_system_e2e.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_threshold_detector.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/tb/tb_usb_data_interface.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/usb_data_interface.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/usb_data_interface_ft2232h.v (100%) rename {9_Firmware => firmware}/9_2_FPGA/xfft_16.v (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_PyQt_Map.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V5.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V5_Demo.py (100%) rename {8_Utils => firmware/9_3_GUI}/GUI_V6.gif (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V6.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V65_Tk.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V6_Demo.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_V7_PyQt.py (100%) rename {9_Firmware => firmware}/9_3_GUI/GUI_versions.txt (100%) rename {9_Firmware => firmware}/9_3_GUI/adi_agc_analysis.py (100%) rename {9_Firmware => firmware}/9_3_GUI/radar_protocol.py (100%) rename {9_Firmware => firmware}/9_3_GUI/requirements_dashboard.txt (100%) rename {9_Firmware => firmware}/9_3_GUI/requirements_pyqt_gui.txt (100%) rename {9_Firmware => firmware}/9_3_GUI/requirements_v7.txt (100%) rename {9_Firmware => firmware}/9_3_GUI/smoke_test.py (100%) rename {9_Firmware => firmware}/9_3_GUI/test_GUI_V65_Tk.py (100%) rename {8_Utils/Python => firmware/9_3_GUI}/test_radar_data.csv (100%) rename {9_Firmware => firmware}/9_3_GUI/test_v7.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/__init__.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/agc_sim.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/dashboard.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/hardware.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/map_widget.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/models.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/processing.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/replay.py (100%) rename {9_Firmware => firmware}/9_3_GUI/v7/software_fpga.py (99%) rename {9_Firmware => firmware}/9_3_GUI/v7/workers.py (100%) rename {9_Firmware => firmware}/tests/cross_layer/.gitignore (100%) rename {9_Firmware => firmware}/tests/cross_layer/adar1000_vm_reference.py (98%) rename {9_Firmware => firmware}/tests/cross_layer/contract_parser.py (100%) rename {9_Firmware => firmware}/tests/cross_layer/stm32_settings_stub.cpp (93%) rename {9_Firmware => firmware}/tests/cross_layer/tb_cross_layer_ft2232h.v (100%) rename {9_Firmware => firmware}/tests/cross_layer/test_cross_layer_contract.py (99%) rename {9_Firmware => firmware}/tools/uart_capture.py (100%) rename {6_Application Notes => hardware/application-notes}/UG-290.pdf (100%) rename {1_Project_Description => hardware/description}/Project_Description.docx (100%) rename {2_Functional Diagram & Interconnection Matrices => hardware/diagrams}/RADAR_V6.drawio (100%) rename {2_Functional Diagram & Interconnection Matrices => hardware/diagrams}/RADAR_V6.jpg (100%) rename {2_Functional Diagram & Interconnection Matrices => hardware/diagrams}/RADAR_V6_V2.png (100%) rename {8_Utils => hardware/mechanical}/0044.jpg (100%) rename {8_Utils => hardware/mechanical}/3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg (100%) rename {8_Utils => hardware/mechanical}/AERIS-10_RADAR.png (100%) rename {8_Utils => hardware/mechanical}/Antenna_Array.jpg (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/142-0731-211.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/AD9523BCPZ.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/AFII-TC-0015.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/Air_Link.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/CONMCX013.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/My_Library.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/My_Library_2.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/My_Library_RADAR.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/My_Library_SDR.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/NRF905.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/QPA2811.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/SF2321D.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr (100%) rename {8_Utils => hardware/mechanical}/Eagle_ CAD_Libs/mmWAVE.lbr (100%) rename {8_Utils => hardware/mechanical}/GUI.jpg (100%) rename {9_Firmware/9_3_GUI => hardware/mechanical}/GUI_V6.gif (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Down_Part_Waveguide.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Enclosure.bak (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Enclosure.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Heat_Sink_Main_Board.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Heat_Sink_PA.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/RADAR_V1.bak (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/RADAR_V1.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/SlipRing.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Upper_Part_Waveguide.dwg (100%) rename {8_Utils => hardware/mechanical}/Mechanical_Drawings/Waveguide.dwg (100%) rename {8_Utils => hardware/mechanical}/Nawfal.png (100%) rename {8_Utils => hardware/mechanical}/PCBWAY.jpg (100%) rename {8_Utils => hardware/mechanical}/Python/CSV_radar.py (100%) rename {8_Utils => hardware/mechanical}/Python/CSV_radar_2.py (100%) rename {8_Utils => hardware/mechanical}/Python/FFT_Ramp_Frequency.py (100%) rename {8_Utils => hardware/mechanical}/Python/Gen_Triangular.py (100%) rename {8_Utils => hardware/mechanical}/Python/Generic_Ramp_Frequency.py (100%) rename {8_Utils => hardware/mechanical}/Python/Generic_Triangular_Frequency.py (100%) rename {8_Utils => hardware/mechanical}/Python/LUT.py (100%) rename {8_Utils => hardware/mechanical}/Python/RADAR_eq.py (100%) rename {8_Utils => hardware/mechanical}/Python/Ramp_Frequency.py (100%) rename {8_Utils => hardware/mechanical}/Python/patch_antenna.py (100%) rename {8_Utils => hardware/mechanical}/Python/small_test_radar_data.csv (100%) rename {9_Firmware/9_3_GUI => hardware/mechanical/Python}/test_radar_data.csv (100%) rename {8_Utils => hardware/mechanical}/RADAR_V6_V2.jpg (100%) rename {8_Utils => hardware/mechanical}/RADAR_V6_V2.png (100%) rename {8_Utils => hardware/mechanical}/SplitRing_test.mp4 (100%) rename {8_Utils => hardware/mechanical}/b79a6fe3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg (100%) rename {3_Power Management => hardware/power}/Power Management V6.xlsx (100%) rename {5_Simulations => hardware/rf-simulations}/AAF_openEMS/aaf_simulation.py (100%) rename {5_Simulations => hardware/rf-simulations}/Antenna/Quartz_Waveguide.py (100%) rename {5_Simulations => hardware/rf-simulations}/Antenna/openems_quartz_slotted_wg_10p5GHz.py (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/DAC_RLPF.dat (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/DAC_RLPF.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/DAC_RLPF.sch (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/Generate_ChirpcsvFile.py (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/dac_output.csv (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/multi_ramp_output.csv (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/multi_ramp_stairs.csv (100%) rename {5_Simulations => hardware/rf-simulations}/DAC_ReconstructionFilter/ramp_output.csv (100%) rename {5_Simulations => hardware/rf-simulations}/E_plane_Kaiser25dB_like.png (100%) rename {5_Simulations => hardware/rf-simulations}/E_plane_cut.png (100%) rename {5_Simulations => hardware/rf-simulations}/Fencing/Via_fencing.py (100%) rename {5_Simulations => hardware/rf-simulations}/Fencing/Via_fencing2.py (100%) rename {5_Simulations => hardware/rf-simulations}/Fencing/via_fence_setup_pitch.png (100%) rename {5_Simulations => hardware/rf-simulations}/Fencing/via_fence_setup_pitch_offset.png (100%) rename {5_Simulations => hardware/rf-simulations}/H_plane_Kaiser25dB_like.png (100%) rename {5_Simulations => hardware/rf-simulations}/H_plane_cut.png (100%) rename {5_Simulations => hardware/rf-simulations}/Heatmap_Kaiser25dB_like.png (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF/IF_BPF.dat (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF/IF_BPF.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF/IF_BPF.sch (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF_Balanced/IF_BPF_Balanced.dat (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF_Balanced/IF_BPF_Balanced.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF_Balanced/IF_BPF_Balanced.sch (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF_Balanced/multiband_signal.csv (100%) rename {5_Simulations => hardware/rf-simulations}/IF_BPF_Balanced/six_tone_signal.csv (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/16_8.m (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/Antenna16_8.m (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/Antenna_array.m (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/DielectricCatalog.csv (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/antenna16_antenna8.m (100%) rename {5_Simulations => hardware/rf-simulations}/Matlab/pattern_data.mat (100%) rename {5_Simulations => hardware/rf-simulations}/QPA2962.dat (100%) rename {5_Simulations => hardware/rf-simulations}/QPA2962.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/QPA2962.sch (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Impedance.dat (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Impedance.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Impedance.sch (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p (100%) rename {5_Simulations => hardware/rf-simulations}/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Drawing1.bak (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Drawing1.dxf (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/Gerber-backups/Gerber-2025-09-21_024138.zip (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Gerber/fp-info-cache (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.net (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/gerber_file.gbr (100%) rename {5_Simulations => hardware/rf-simulations}/Sim_BPF_Te_100um/qucs2grb_log.txt (100%) rename {5_Simulations => hardware/rf-simulations}/Slotted_DielectricFilled_Waveguide.m (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF/Stub_BPF.dat (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF/Stub_BPF.net (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF/Stub_BPF.sch (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF_V5.dat (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF_V5.dpl (100%) rename {5_Simulations => hardware/rf-simulations}/Stub_BPF_V5.sch (100%) rename {5_Simulations => hardware/rf-simulations}/array_pattern_Kaiser25dB_like.py (100%) rename {5_Simulations => hardware/rf-simulations}/array_pattern_heatmap.png (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/et (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/ht (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/port_it1A (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/port_it1B (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/port_ut1A (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/port_ut1B (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/port_ut1C (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_32/wg_alumina_32.xml (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/et (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/ht (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/port_it1A (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/port_it1B (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/port_ut1A (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/port_ut1B (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/port_ut1C (100%) rename {5_Simulations => hardware/rf-simulations}/sim_wg_alumina_fast/wg_alumina.xml (100%) rename {5_Simulations => hardware/rf-simulations}/slot_layout_taper32.csv (100%) rename {5_Simulations => hardware/rf-simulations}/wg_alumina_slotted_openems.m (100%) delete mode 100644 montecarlo_stats.json create mode 100644 parts/README.md create mode 100644 parts/cost.md rename {7_Components Datasheets and Application notes => parts/datasheets}/60124102122403.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/8-12GHz MTH801C-20 SMA Broadband Circulator .pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9484/AD9434_AD9484_Schematic.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9484/AD9484.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9484/RX_Chain_Gain_Noise_Summary_ABAC_Radar.docx (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9484/UG-290.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9484/ad8352.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AD9708.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ADAR1000.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ADF4382A/ADF4382A.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ADF4382A/eval_adf4382a_ug_2185-3392420.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ADM7151.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/AT93C46A.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/DS_FT2232H.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/DS_FT232RN.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/EP4RKU_2b-1858448.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/FR2-SMA-KFD0405A_2025-08-11.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/LTC5552f.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/LTC6419fa.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/M3SWA2-34DR+.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/MAX1449-3468915.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/MMIQA-0218HPSM-Integrated Drive GaAs MMIC IQ Mixer.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/MTX2-143+.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/PMA2-123LNW+.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/PMA5_123_3W_2b-3577903.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPA1013D Data Sheet.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPA2962/QPA2962 Data Sheet.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_25C.s2p (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_85C.s2p (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_n40C.s2p (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/QPM1021 Data Sheet.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/RO4000 Laminates RO4003C and RO4350B - Data Sheet (1).pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/RO4000 Laminates RO4003C and RO4350B - Data Sheet.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/SMIQ-5143H+.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/STUW81300TR.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/TGA2623_Data_Sheet-1518452.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ads7830.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/adtr1107.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/attenuator_n_catalog_partition37_en.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/dac7578.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/hr2220p601r-10-datasheet.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/ina241a.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/lm2663.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/max20029-max20029d.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/opa703.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/tmp35_36_37.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/tps562201.pdf (100%) rename {7_Components Datasheets and Application notes => parts/datasheets}/tps7a8300.pdf (100%) create mode 100644 parts/parts-list.csv delete mode 100755 run_simulation.sh rename {4_Schematics and Boards Layout => schematics}/4_4_Board Stack-up/Stack_Hybrid.png (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#5 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#6 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#7 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#8 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#9 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Patch/8x16/place.scr (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Antennas/Waveguide/Dielectric_Filled_Waveguide_Array_Spec.docx (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/MainBoard/RADAR_Main_Board.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/MainBoard/RADAR_Main_Board.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/PowerAmplifierBoard/RF_PA.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/PowerAmplifierBoard/RF_PA.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/PowerBoard/PowerBoard.brd (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/PowerBoard/PowerBoard.sch (100%) rename {4_Schematics and Boards Layout => schematics}/4_6_Schematics/Stack_Hybrid.png (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/CPL.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L10 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L5 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L6 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L7 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L8 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L9 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bsk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drd (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.dri (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.gpi (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.oln (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.slk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.tps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/BOM.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/BOM_PA.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/CPL.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.L1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.L2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.L3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.L4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.adb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.adt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.bgl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.bps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.bsk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.drd (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.dri (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.drl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.fab (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.gpi (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.oln (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.slk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.smb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.smt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.tgl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA.tps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA_MNB (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PA/RF_PA_MNT (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/CPL.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bsk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drd (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.dri (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.gpi (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.oln (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.slk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.tps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/BOM.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/CPL.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bot (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsp (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.csv (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drd (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.dri (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.gpi (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.oln (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.slk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.top (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard.tsp (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_PowerBoard/PowerBoard_CSV_BOM (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/CPL.xlsx (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L1 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L2 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L3 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L4 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L5 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L6 (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bsk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.csv (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drd (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.dri (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drl (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.gpi (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.oln (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.slk (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.tps (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_BOM_CSV (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnb (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnt (100%) rename {4_Schematics and Boards Layout => schematics}/4_7_Production Files/PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf (100%) delete mode 100644 simulate_city_defense_radar.py delete mode 100644 simulate_dual_radar_tracking.py delete mode 100644 simulate_interceptor_drones.py delete mode 100644 simulate_three_radar_tracking.py delete mode 100644 simulate_trajectory_precision.py rename {defense_sim_v2 => simulation}/.gitignore (100%) rename {defense_sim_v2 => simulation}/DEMO_USER.txt (100%) rename {defense_sim_v2 => simulation}/PROJECT_SPEC.md (95%) rename {defense_sim_v2 => simulation}/README.md (85%) rename {defense_sim_v2 => simulation}/deploy/defense-sim-backend.service (55%) rename {defense_sim_v2 => simulation}/deploy/supabase/compose.yml (100%) rename {defense_sim_v2 => simulation}/deploy/supabase/frontend.conf (100%) rename {defense_sim_v2 => simulation}/deploy/supabase/migrate.sql (100%) rename {defense_sim_v2 => simulation}/deploy/supabase/roles.sql (100%) rename {defense_sim_v2 => simulation}/deploy/traefik-defense-sim-v2.yml (100%) rename {defense_sim_v2 => simulation}/frontend/.dockerignore (100%) rename {defense_sim_v2 => simulation}/frontend/.editorconfig (100%) rename {defense_sim_v2 => simulation}/frontend/.env.example (94%) rename {defense_sim_v2 => simulation}/frontend/.github/FUNDING.yml (100%) rename {defense_sim_v2 => simulation}/frontend/.github/workflows/ci.yml (100%) rename {defense_sim_v2 => simulation}/frontend/.gitignore (100%) rename {defense_sim_v2 => simulation}/frontend/.npmrc (100%) rename {defense_sim_v2 => simulation}/frontend/.vscode/extensions.json (100%) rename {defense_sim_v2 => simulation}/frontend/.vscode/settings.json (100%) rename {defense_sim_v2 => simulation}/frontend/Dockerfile (100%) rename {defense_sim_v2 => simulation}/frontend/README.md (100%) rename {defense_sim_v2 => simulation}/frontend/components.json (100%) rename {defense_sim_v2 => simulation}/frontend/cypress.config.ts (100%) rename {defense_sim_v2 => simulation}/frontend/cypress/e2e/auth.spec.ts (100%) rename {defense_sim_v2 => simulation}/frontend/cypress/e2e/basic.spec.ts (100%) rename {defense_sim_v2 => simulation}/frontend/cypress/tsconfig.json (100%) rename {defense_sim_v2 => simulation}/frontend/eslint.config.js (100%) rename {defense_sim_v2 => simulation}/frontend/index.html (100%) rename {defense_sim_v2 => simulation}/frontend/locales/README.md (100%) rename {defense_sim_v2 => simulation}/frontend/locales/en.yml (100%) rename {defense_sim_v2 => simulation}/frontend/netlify.toml (100%) rename {defense_sim_v2 => simulation}/frontend/package.json (100%) rename {defense_sim_v2 => simulation}/frontend/pnpm-lock.yaml (100%) rename {defense_sim_v2 => simulation}/frontend/pnpm-workspace.yaml (100%) rename {defense_sim_v2 => simulation}/frontend/public/_headers (100%) rename {defense_sim_v2 => simulation}/frontend/public/favicon-dark.svg (100%) rename {defense_sim_v2 => simulation}/frontend/public/favicon.svg (100%) rename {defense_sim_v2 => simulation}/frontend/public/pwa-192x192.png (100%) rename {defense_sim_v2 => simulation}/frontend/public/pwa-512x512.png (100%) rename {defense_sim_v2 => simulation}/frontend/public/safari-pinned-tab.svg (100%) rename {defense_sim_v2 => simulation}/frontend/src/App.vue (85%) rename {defense_sim_v2 => simulation}/frontend/src/auto-imports.d.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components.d.ts (99%) rename {defense_sim_v2 => simulation}/frontend/src/components/AppSidebar.vue (96%) rename {defense_sim_v2 => simulation}/frontend/src/components/DarkModeSwitcher.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/LanguageSwitcher.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/README.md (100%) create mode 100644 simulation/frontend/src/components/RadarConsolePanel.vue create mode 100644 simulation/frontend/src/components/RadarPlot.vue rename {defense_sim_v2 => simulation}/frontend/src/components/SimulationScene.vue (51%) rename {defense_sim_v2 => simulation}/frontend/src/components/TheInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/accordion/Accordion.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/accordion/AccordionContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/accordion/AccordionItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/accordion/AccordionTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/accordion/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialog.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogAction.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogCancel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/AlertDialogTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert-dialog/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert/Alert.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert/AlertDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert/AlertTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/alert/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/aspect-ratio/AspectRatio.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/aspect-ratio/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/avatar/Avatar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/avatar/AvatarFallback.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/avatar/AvatarImage.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/avatar/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/badge/Badge.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/badge/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/Breadcrumb.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbLink.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbList.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbPage.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/BreadcrumbSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/breadcrumb/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button-group/ButtonGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button-group/ButtonGroupSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button-group/ButtonGroupText.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button-group/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button/Button.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/button/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/Calendar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarCell.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarCellTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarGrid.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarGridBody.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarGridHead.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarGridRow.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarHeadCell.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarHeading.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarNextButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/CalendarPrevButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/calendar/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/Card.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/CardContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/CardDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/CardFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/CardHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/CardTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/card/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/Carousel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/CarouselContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/CarouselItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/CarouselNext.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/CarouselPrevious.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/interface.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/carousel/useCarousel.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/ChartCrosshair.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/ChartLegend.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/ChartSingleTooltip.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/ChartTooltip.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/interface.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/chart/mountChartTooltip.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/checkbox/Checkbox.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/checkbox/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/collapsible/Collapsible.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/collapsible/CollapsibleContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/collapsible/CollapsibleTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/collapsible/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/Combobox.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxAnchor.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxEmpty.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxList.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/ComboboxTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/combobox/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/Command.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandDialog.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandEmpty.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandList.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/CommandShortcut.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/command/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenu.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuCheckboxItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuPortal.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuRadioGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuRadioItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuShortcut.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuSub.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuSubContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuSubTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/ContextMenuTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/context-menu/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/Dialog.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogClose.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogScrollContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/DialogTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dialog/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/Drawer.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerOverlay.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/DrawerTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/drawer/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenu.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuSub.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/dropdown-menu/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/Empty.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/EmptyContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/EmptyDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/EmptyHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/EmptyMedia.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/EmptyTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/empty/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/Field.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldError.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldLegend.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldSet.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/FieldTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/field/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/FormControl.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/FormDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/FormItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/FormLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/FormMessage.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/injectionKeys.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/form/useFormField.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/hover-card/HoverCard.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/hover-card/HoverCardContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/hover-card/HoverCardTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/hover-card/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroupAddon.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroupButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroupInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroupText.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/InputGroupTextarea.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input-group/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input/Input.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/input/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/Item.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemActions.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemMedia.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/ItemTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/item/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/kbd/Kbd.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/kbd/KbdGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/kbd/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/label/Label.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/label/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/Menubar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarCheckboxItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarMenu.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarRadioGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarRadioItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarShortcut.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarSub.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarSubContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarSubTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/MenubarTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/menubar/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenu.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuIndicator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuLink.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuList.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/NavigationMenuViewport.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/navigation-menu/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/NumberField.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/NumberFieldContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/NumberFieldDecrement.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/NumberFieldIncrement.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/NumberFieldInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/number-field/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/Pagination.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationEllipsis.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationFirst.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationLast.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationNext.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/PaginationPrevious.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pagination/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pin-input/PinInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pin-input/PinInputGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pin-input/PinInputSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pin-input/PinInputSlot.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/pin-input/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/popover/Popover.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/popover/PopoverContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/popover/PopoverTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/popover/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/progress/Progress.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/progress/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/radio-group/RadioGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/radio-group/RadioGroupItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/radio-group/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarCell.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarGrid.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarGridBody.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarGridHead.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarGridRow.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarHeadCell.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarHeading.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarNextButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/RangeCalendarPrevButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/range-calendar/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/resizable/ResizableHandle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/resizable/ResizablePanelGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/resizable/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/scroll-area/ScrollArea.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/scroll-area/ScrollBar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/scroll-area/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/Select.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectItemText.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectScrollDownButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectScrollUpButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/SelectValue.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/select/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/separator/Separator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/separator/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/Sheet.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetClose.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/SheetTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sheet/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/Sidebar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarGroupAction.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarGroupContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarGroupLabel.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarInset.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenu.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuAction.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuBadge.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuButtonChild.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuSkeleton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuSub.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuSubButton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarMenuSubItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarProvider.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarRail.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/SidebarTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sidebar/utils.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/skeleton/Skeleton.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/skeleton/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/slider/Slider.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/slider/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sonner/Sonner.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/sonner/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/spinner/Spinner.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/spinner/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/Stepper.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperDescription.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperIndicator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperSeparator.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperTitle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/StepperTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/stepper/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/switch/Switch.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/switch/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/Table.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableBody.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableCaption.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableCell.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableEmpty.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableFooter.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableHead.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableHeader.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/TableRow.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/table/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tabs/Tabs.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tabs/TabsContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tabs/TabsList.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tabs/TabsTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tabs/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/TagsInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/TagsInputInput.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/TagsInputItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/TagsInputItemDelete.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/TagsInputItemText.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tags-input/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/textarea/Textarea.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/textarea/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/toggle-group/ToggleGroup.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/toggle-group/ToggleGroupItem.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/toggle-group/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/toggle/Toggle.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/toggle/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tooltip/Tooltip.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tooltip/TooltipContent.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tooltip/TooltipProvider.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tooltip/TooltipTrigger.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/components/ui/tooltip/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/composables/dark.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/composables/useAuth.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/composables/useLogout.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/composables/useSimulationSocket.ts (60%) rename {defense_sim_v2 => simulation}/frontend/src/config.ts (95%) rename {defense_sim_v2 => simulation}/frontend/src/devtools/I18nAudit.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/devtools/useI18nAudit.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/layouts/404.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/layouts/README.md (100%) rename {defense_sim_v2 => simulation}/frontend/src/layouts/default.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/layouts/login.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/layouts/with-sidebar.vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/auth/authErrorHandler.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/auth/authReservedPaths.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/auth/inviteRedirect.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/i18n-audit/index.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/i18n-audit/lmstudio.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/i18n-audit/scanner.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/simulationRuns.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/supabaseClient.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/ui-locale-prefs.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/lib/utils.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/main.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/README.md (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/auth.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/dev-i18n-audit.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/i18n.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/nprogress.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/pinia.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/pwa.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/modules/router-auth.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/pages/README.md (100%) rename {defense_sim_v2 => simulation}/frontend/src/pages/[...all].vue (100%) rename {defense_sim_v2 => simulation}/frontend/src/pages/index.vue (76%) rename {defense_sim_v2 => simulation}/frontend/src/pages/login.vue (97%) rename {defense_sim_v2 => simulation}/frontend/src/route-map.d.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/shims.d.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/stores/adminAccess.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/stores/auth.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/styles/main.css (100%) rename {defense_sim_v2 => simulation}/frontend/src/styles/markdown.css (100%) rename {defense_sim_v2 => simulation}/frontend/src/types.ts (100%) rename {defense_sim_v2 => simulation}/frontend/src/types/database.ts (100%) create mode 100644 simulation/frontend/src/types/simulation.ts rename {defense_sim_v2 => simulation}/frontend/src/utils/cldrPluralRules.ts (100%) rename {defense_sim_v2 => simulation}/frontend/supabase/migrations/20260930000000_simulation_runs.sql (100%) rename {defense_sim_v2 => simulation}/frontend/test/__snapshots__/component.test.ts.snap (100%) rename {defense_sim_v2 => simulation}/frontend/test/auth.test.ts (100%) rename {defense_sim_v2 => simulation}/frontend/test/basic.test.ts (100%) rename {defense_sim_v2 => simulation}/frontend/test/component.test.ts (100%) rename {defense_sim_v2 => simulation}/frontend/tsconfig.json (100%) rename {defense_sim_v2 => simulation}/frontend/uno.config.ts (100%) rename {defense_sim_v2 => simulation}/frontend/vite.config.ts (98%) rename {defense_sim_v2 => simulation}/latest_goal.md (90%) rename {defense_sim_v2 => simulation}/physics_auditing_review_and_gaps.md (97%) rename {defense_sim_v2 => simulation}/prompt.txt (100%) rename {defense_sim_v2 => simulation}/pyproject.toml (78%) create mode 100644 simulation/radar_gui_port.md rename {defense_sim_v2 => simulation}/rebuild_restart.sh (100%) rename {defense_sim_v2 => simulation}/scripts/bootstrap_auth.py (100%) rename {defense_sim_v2 => simulation}/scripts/create_demo_user.py (100%) create mode 100644 simulation/src/defense_sim/__init__.py rename {defense_sim_v2 => simulation}/src/defense_sim/cli.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/entities/__init__.py (100%) create mode 100644 simulation/src/defense_sim/entities/drone.py rename {defense_sim_v2 => simulation}/src/defense_sim/entities/projectile.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/guidance/__init__.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/guidance/activation.py (100%) create mode 100644 simulation/src/defense_sim/guidance/ascent.py create mode 100644 simulation/src/defense_sim/guidance/trajectory.py rename {defense_sim_v2 => simulation}/src/defense_sim/physics/__init__.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/atmosphere.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/environment.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/events.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/flight.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/integrator.py (82%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/reference.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/turbulence.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/physics/validation.py (100%) create mode 100644 simulation/src/defense_sim/radar/__init__.py create mode 100644 simulation/src/defense_sim/radar/console.py create mode 100644 simulation/src/defense_sim/radar/data/plfm_gui_samples.csv create mode 100644 simulation/src/defense_sim/radar/data/plfm_gui_samples.iq.xz create mode 100644 simulation/src/defense_sim/radar/replay_data.py create mode 100644 simulation/src/defense_sim/radar/v6_demo.py rename {defense_sim_v2 => simulation}/src/defense_sim/sensors/__init__.py (100%) create mode 100644 simulation/src/defense_sim/sensors/devices.py rename {defense_sim_v2 => simulation}/src/defense_sim/sensors/models.py (100%) create mode 100644 simulation/src/defense_sim/sensors/signal_chain.py rename {defense_sim_v2 => simulation}/src/defense_sim/sensors/tracking.py (59%) rename {defense_sim_v2 => simulation}/src/defense_sim/server/__init__.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/server/auth.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/server/events.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/server/socketio_server.py (62%) rename {defense_sim_v2 => simulation}/src/defense_sim/simulation/__init__.py (100%) create mode 100644 simulation/src/defense_sim/simulation/engine.py rename {defense_sim_v2 => simulation}/src/defense_sim/simulation/presets.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/simulation/scenarios.py (89%) rename {defense_sim_v2 => simulation}/src/defense_sim/statistics/__init__.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/statistics/metrics.py (100%) rename {defense_sim_v2 => simulation}/src/defense_sim/statistics/monte_carlo.py (100%) rename {defense_sim_v2 => simulation}/tests/test_ascent.py (58%) create mode 100644 simulation/tests/test_audit_regressions.py rename {defense_sim_v2 => simulation}/tests/test_auth.py (100%) rename {defense_sim_v2 => simulation}/tests/test_flight_adapters.py (100%) rename {defense_sim_v2 => simulation}/tests/test_physics.py (100%) rename {defense_sim_v2 => simulation}/tests/test_presets.py (100%) create mode 100644 simulation/tests/test_radar_console.py create mode 100644 simulation/tests/test_radar_measurements.py rename {defense_sim_v2 => simulation}/tests/test_server_runtime.py (100%) create mode 100644 simulation/tests/test_standby_and_trails.py create mode 100644 simulation/tools/export_replay_iq.py create mode 100644 simulation/tools/probe_signal_chain.py delete mode 100644 test_defense_sim.py diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index be7637a..47b3885 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -46,8 +46,8 @@ jobs: - name: Unit tests run: > uv run pytest - 9_Firmware/9_3_GUI/test_GUI_V65_Tk.py - 9_Firmware/9_3_GUI/test_v7.py + firmware/9_3_GUI/test_GUI_V65_Tk.py + firmware/9_3_GUI/test_v7.py -v --tb=short # =========================================================================== @@ -66,7 +66,7 @@ jobs: - name: Build and run MCU tests run: make test - working-directory: 9_Firmware/9_1_Microcontroller/tests + working-directory: firmware/9_1_Microcontroller/tests # =========================================================================== # FPGA RTL Regression (25 testbenches + lint) @@ -83,7 +83,7 @@ jobs: - name: Run full FPGA regression run: bash run_regression.sh - working-directory: 9_Firmware/9_2_FPGA + working-directory: firmware/9_2_FPGA # =========================================================================== # Cross-Layer Contract Tests (Python ↔ Verilog ↔ C) @@ -112,5 +112,5 @@ jobs: - name: Run cross-layer contract tests run: > uv run pytest - 9_Firmware/tests/cross_layer/test_cross_layer_contract.py + firmware/tests/cross_layer/test_cross_layer_contract.py -v --tb=short diff --git a/.gitignore b/.gitignore index 7e03976..a4a35e1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,35 +3,35 @@ *.vcd # Debug / scratch RTL (not part of the design) -9_Firmware/9_2_FPGA/debug_*.v -9_Firmware/9_2_FPGA/tb/tb_fft_debug*.v -9_Firmware/9_2_FPGA/tb/tb_fft_mini*.v -9_Firmware/9_2_FPGA/tb/tb_bram_debug.v +firmware/9_2_FPGA/debug_*.v +firmware/9_2_FPGA/tb/tb_fft_debug*.v +firmware/9_2_FPGA/tb/tb_fft_mini*.v +firmware/9_2_FPGA/tb/tb_bram_debug.v # Local simulation artifacts and CSV outputs -9_Firmware/9_2_FPGA/cic_*.csv -9_Firmware/9_2_FPGA/fir_*.csv -9_Firmware/9_2_FPGA/nco_*.csv -9_Firmware/9_2_FPGA/ddc_*.csv -9_Firmware/9_2_FPGA/mf_pipeline_output.csv -9_Firmware/9_2_FPGA/mf_chain_autocorr.csv -9_Firmware/9_2_FPGA/rbd_mode00_ramp.csv -9_Firmware/9_2_FPGA/rbd_mode01_peak.csv -9_Firmware/9_2_FPGA/rbd_mode10_avg.csv -9_Firmware/9_2_FPGA/rbd_mode10_ramp.csv -9_Firmware/9_2_FPGA/rmc_autoscan.csv -9_Firmware/9_2_FPGA/tb/mf_chain_autocorr.csv -9_Firmware/9_2_FPGA/tb/rbd_mode00_ramp.csv -9_Firmware/9_2_FPGA/tb/rbd_mode01_peak.csv -9_Firmware/9_2_FPGA/tb/rbd_mode10_avg.csv -9_Firmware/9_2_FPGA/tb/rbd_mode10_ramp.csv -9_Firmware/9_2_FPGA/tb/rmc_autoscan.csv -9_Firmware/9_2_FPGA/tb_usb_data_interface.csv +firmware/9_2_FPGA/cic_*.csv +firmware/9_2_FPGA/fir_*.csv +firmware/9_2_FPGA/nco_*.csv +firmware/9_2_FPGA/ddc_*.csv +firmware/9_2_FPGA/mf_pipeline_output.csv +firmware/9_2_FPGA/mf_chain_autocorr.csv +firmware/9_2_FPGA/rbd_mode00_ramp.csv +firmware/9_2_FPGA/rbd_mode01_peak.csv +firmware/9_2_FPGA/rbd_mode10_avg.csv +firmware/9_2_FPGA/rbd_mode10_ramp.csv +firmware/9_2_FPGA/rmc_autoscan.csv +firmware/9_2_FPGA/tb/mf_chain_autocorr.csv +firmware/9_2_FPGA/tb/rbd_mode00_ramp.csv +firmware/9_2_FPGA/tb/rbd_mode01_peak.csv +firmware/9_2_FPGA/tb/rbd_mode10_avg.csv +firmware/9_2_FPGA/tb/rbd_mode10_ramp.csv +firmware/9_2_FPGA/tb/rmc_autoscan.csv +firmware/9_2_FPGA/tb_usb_data_interface.csv # Co-sim intermediate CSVs (regenerated by scripts) -9_Firmware/9_2_FPGA/tb/cosim/rtl_doppler_*.csv -9_Firmware/9_2_FPGA/tb/cosim/compare_doppler_*.csv -9_Firmware/9_2_FPGA/tb/cosim/rtl_multiseg_*.csv +firmware/9_2_FPGA/tb/cosim/rtl_doppler_*.csv +firmware/9_2_FPGA/tb/cosim/compare_doppler_*.csv +firmware/9_2_FPGA/tb/cosim/rtl_multiseg_*.csv # macOS .DS_Store @@ -44,13 +44,13 @@ __pycache__/ 10_docs/ # Local simulation workspaces and generated outputs -5_Simulations/generated/ -5_Simulations/aeris10_antenna_sim.py -5_Simulations/aeris10_radar_sim.py +hardware/rf-simulations/generated/ +hardware/rf-simulations/aeris10_antenna_sim.py +hardware/rf-simulations/aeris10_radar_sim.py # Local FPGA report dumps and scratch constraints -9_Firmware/9_2_FPGA/reports/ -9_Firmware/9_2_FPGA/synth_only.xdc +firmware/9_2_FPGA/reports/ +firmware/9_2_FPGA/synth_only.xdc # Local timing closure report snapshots build*_reports/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 448b518..81ef7b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,11 +20,13 @@ Never run bare package installation commands without the `sfw` prefix. | Path | Contents | |------|----------| -| `4_Schematics and Boards Layout/` | KiCad schematics, Gerbers, BOM/CPL | -| `9_Firmware/9_1_Microcontroller/` | STM32 MCU C/C++ firmware and unit tests | -| `9_Firmware/9_2_FPGA/` | Verilog RTL, constraints, testbenches, build scripts | -| `9_Firmware/9_3_GUI/` | Python radar dashboard (Tkinter/PyQt6) and CLI tools | -| `9_Firmware/tests/cross_layer/` | Python-based system invariant/contract tests | +| `simulation/` | Overwatch | +| `schematics/` | Schematics, Gerbers, BOM/CPL | +| `parts/` | Consolidated parts list and datasheets | +| `firmware/9_1_Microcontroller/` | STM32 MCU C/C++ firmware and unit tests | +| `firmware/9_2_FPGA/` | Verilog RTL, constraints, testbenches, build scripts | +| `firmware/9_3_GUI/` | Python radar dashboard (Tkinter/PyQt6) and CLI tools | +| `firmware/tests/cross_layer/` | Python-based system invariant/contract tests | | `docs/` | GitHub Pages documentation site | ## Code Standards & Tooling @@ -57,26 +59,26 @@ We use GitHub Actions for CI, which runs four main jobs on every PR. Run these l ### 1. Python & Linting ```bash uv run ruff check . -cd 9_Firmware/9_3_GUI +cd firmware/9_3_GUI uv run pytest test_GUI_V65_Tk.py test_v7.py -v ``` ### 2. FPGA Regression ```bash -cd 9_Firmware/9_2_FPGA +cd firmware/9_2_FPGA bash run_regression.sh ``` This runs five phases (Lint, Changed Modules, Integration, Signal Processing, Infrastructure, and **P0 Adversarial Tests**). All must pass. ### 3. MCU Unit Tests ```bash -cd 9_Firmware/9_1_Microcontroller/tests +cd firmware/9_1_Microcontroller/tests make clean && make ``` ### 4. Cross-Layer Contract Tests ```bash -uv run pytest 9_Firmware/tests/cross_layer/test_cross_layer_contract.py -v +uv run pytest firmware/tests/cross_layer/test_cross_layer_contract.py -v ``` ## Before merging: CI checklist @@ -102,9 +104,9 @@ All PRs must pass CI: - [ ] `uv run ruff check .` — no lint errors - [ ] `uv run pytest test_GUI_V65_Tk.py test_v7.py -v` — all pass -- [ ] `cd 9_Firmware/9_2_FPGA && bash run_regression.sh` — all 5 phases pass -- [ ] `cd 9_Firmware/9_1_Microcontroller/tests && make clean && make` — pass -- [ ] `uv run pytest 9_Firmware/tests/cross_layer/test_cross_layer_contract.py` — pass +- [ ] `cd firmware/9_2_FPGA && bash run_regression.sh` — all 5 phases pass +- [ ] `cd firmware/9_1_Microcontroller/tests && make clean && make` — pass +- [ ] `uv run pytest firmware/tests/cross_layer/test_cross_layer_contract.py` — pass - [ ] `git diff --check` — no whitespace issues - [ ] PR targets `develop` branch diff --git a/DEFENSE_SIMULATION.md b/DEFENSE_SIMULATION.md deleted file mode 100644 index 469b409..0000000 --- a/DEFENSE_SIMULATION.md +++ /dev/null @@ -1,206 +0,0 @@ -# Generalized Projectile Defense Simulation - -## Overview - -This simulation models a realistic defense scenario where an attack projectile (drone, missile, or ballistic re-entry vehicle) approaches a city defended by a ring of radars and interceptor drones. The simulation uses proper physics, realistic flight profiles, and validated error models. - -It is **generalized** — the attack profile is selected via **presets** for different projectile types. Each preset defines the speed, cruise altitude band, descent geometry, and terminal altitude. The default preset is the jet-powered **Shahed-238 (Geran-3)**. All attack parameters are also editable manually for custom scenarios. - -## Projectile Presets - -| Preset | Type | Speed | Cruise Alt | Descent Start | Terminal Alt | Notes | -|--------|------|-------|-----------|---------------|--------------|-------| -| `shahed-136` | Prop drone (Geran-2) | 50 m/s | 100–300 m | 5 km | 0 m | Slow, low-altitude | -| `shahed-238` | Jet drone (Geran-3) | 150 m/s | 1000–2000 m | 8 km | 200 m | Default; fast, mid-altitude | -| `cruise-missile` | Cruise missile | 300 m/s | 50–150 m | 5 km | 0 m | Fast, sea-skimming | -| `ballistic-reentry` | Ballistic re-entry | 800 m/s | 60000–80000 m | 40 km | 0 m | Very fast, high-altitude entry | -| `prop-drone` | Small UAS | 30 m/s | 100–300 m | 3 km | 0 m | Slow, low-altitude | - -### Shahed-238 Specifications (Jet-Powered Variant) - -Based on research of open-source intelligence and technical analysis: - -| Parameter | Value | Notes | -|-----------|-------|-------| -| Speed (cruise) | ~150 m/s (540 km/h) | 3-4x faster than Shahed-136 | -| Cruise altitude | 1000-2000 m | Typical operational band | -| Terminal altitude | 200 m | Descent target altitude | -| Descent start | ~8 km from target | Gradual descent begins | -| Warhead | 30-50 kg | High explosive | -| Guidance | GPS/INS + terminal seeker | Autonomous | -| Range | ~1500-2000 km | One-way attack | - -Sources: -- [CSIS Missile Threat - Shahed-238](https://missilethreat.csis.org/missile/shahed-238/) -- [BattlePolicy - Shahed-238](https://www.battlepolicy.com/shahed-238/) -- [Wikipedia - HESA Shahed 136](https://en.wikipedia.org/wiki/HESA_Shahed_136) -- [drone-warfare.com - Shahed variants](https://drone-warfare.com/research/shahed-136/) - -## Flight Profile - -Each preset follows a realistic two-phase flight profile: - -1. **Cruise phase**: Maintains constant altitude (within the preset's cruise band, randomized per run) at cruise speed -2. **Descent phase**: Begins `descent_start` distance from the target, gradually descends to the preset's terminal altitude - -The descent is gradual (not a nosedive), consistent with reported loitering-munition attack patterns. The projectile uses GPS/INS navigation to follow a pre-planned waypoint course, with a terminal seeker for the final approach. For the ballistic re-entry preset, the high cruise altitude and long descent start model a high-altitude entry with a terminal pull-down. - -## Defense System - -### Radar Network -- **8 AERIS-10 radars** positioned in a ring around the city (2 km outside city radius) -- Each radar has **20 km range** -- Single-measurement accuracy: **±20 m (1σ)** -- Detection requires target to be within radar range -- Multiple radars improve position accuracy: σ_combined = σ_single / √n - -### Interceptor Drones -- **24 drones** positioned in a ring around the city (8 km outside city radius) -- Drone speed: **100 m/s** (slower than most presets' cruise speed, e.g. Shahed-238 at 150 m/s) -- IR homing range: **5 km** -- IR tracking accuracy: **±3 m (1σ)** -- Kill radius: **20 m** (3D) -- **3 closest drones** launch per threat (selected by fastest viable intercept time) - -## Physics Models - -### 1. Radar Detection -Each radar measures: -- Range (with Gaussian noise, σ = 20 m) -- Azimuth (with noise proportional to 1/distance) -- Elevation (with noise proportional to 1/distance) - -The noise model reflects real radar behavior: angular accuracy improves with range, but absolute position error grows. - -### 2. Position Estimation -The 3D position is estimated by averaging the individual 3D point estimates from each radar (bearing + range). This is a least-squares estimate that properly constrains all three coordinates (x, y, z), including altitude. - -**Key insight**: With coplanar radars (all at z=0), range measurements alone cannot determine altitude. The bearing (azimuth + elevation) measurements are required to constrain the z-coordinate. - -### 3. Trajectory Estimation -The velocity is estimated by linear regression of position vs. time: -``` -pos(t) = pos0 + vel * t -``` -The slope (vel) is the estimated velocity. R² measures fit quality. The standard error of the slope decreases as more data points accumulate: σ_vel = σ_pos / √(Sxx), where Sxx = Σ(t - t̄)². - -**This is the key mechanism by which error decreases with more data points**: the best-fit line converges as more observations are added. - -### 4. Intercept Calculation -The drone intercept solves the classic pursuer-target problem: -``` -|drone_pos + v_d * t - target_pos - v_s * t| = 0 -``` -where v_d = drone_speed * d (d is a unit vector). - -This reduces to a quadratic in t: -``` -(|v_s|² - v_d²) * t² + 2*(rel_pos · v_s) * t + |rel_pos|² = 0 -``` - -The **smallest positive root** gives the earliest intercept time. The intercept point is where the target will be at that time. - -**Critical insight**: A slower pursuer (drone at 100 m/s vs a faster target such as Shahed-238 at 150 m/s) can only intercept if: -- The target is moving TOWARD the pursuer (rel_pos · v_s < 0) -- The geometry is favorable (drones positioned in the approach corridor) -- The intercept happens before the target reaches the city - -### 5. Drone Guidance -Drones fly in 3D straight lines toward the computed intercept point. The intercept point is recomputed every 5 seconds as new trajectory estimates become available (proportional navigation). When within 5 km, the drone switches to IR homing for final precision. - -### 6. Error Propagation -- Radar position error: σ_pos = 20/√n m (decreases with data points) -- 95% confidence interval: 1.96 * σ_pos -- IR error: σ_IR = 3/√n_drones m (decreases with tracking drones) -- Combined error: σ_combined = √(σ_radar² + σ_IR²) - -## Validation Tests - -The simulation is validated against known analytical solutions: - -| Test | Description | Result | -|------|-------------|--------| -| Trajectory continuity | Target speed is constant, altitude profile correct | PASS | -| 1D intercept | Analytical solution: t = 48 s for specific geometry | PASS (t = 48.0 s) | -| No-solution case | Target moving away, no intercept possible | PASS (graceful fallback) | -| 3D intercept | Intercept altitude matches target altitude | PASS | -| Radar detection | In-range detected, out-of-range not | PASS | -| Position estimation | Error < 30 m with 3 radars | PASS (10.2 m) | -| Trajectory estimation | Velocity error < 10 m/s | PASS (0.00 m/s) | -| Simulation runs | Full simulation completes without errors | PASS | -| Interception rate | Rate is within [0, 100]% for default preset | PASS (~67%) | -| Presets vary rates | Slow/low target >= fast/high target intercept rate | PASS | -| Drone selection | Only viable drones launched | PASS | - -**All 11 tests pass.** - -## Monte Carlo Results (100 Trials per Preset) - -| Preset | Interception Rate | Avg Detect | Avg Collision | Avg Impact | -|--------|-------------------|-----------|---------------|-----------| -| `shahed-136` (prop, low) | **100%** | 7.0 s | 88.5 s | — | -| `shahed-238` (jet, mid) | **68%** | 27.2 s | 85.8 s | 170.0 s | -| `cruise-missile` (fast, low) | **36%** | 64.7 s | 98.9 s | 137.6 s | -| `ballistic-reentry` (very fast, high) | **0%** | 110.9 s | — | 114.6 s | -| `prop-drone` (slow, low) | **100%** | 1.0 s | 44.2 s | — | - -(Exact values are regenerated each run via `montecarlo_stats.json`; the table shows representative values.) - -## Key Findings - -1. **Interception rate scales with target speed and altitude.** Slow, low-altitude projectiles (Shahed-136, small UAS) are nearly always intercepted, while fast, high-altitude ones (ballistic re-entry) are effectively unstoppable by this drone defense. The jet-powered Shahed-238 sits in the middle at ~68%. - -2. **Detection happens before the target is in the danger zone.** The target enters radar range (20 km) and is detected after accumulating 3+ observations. Faster targets get detected later in absolute terms but with less margin. - -3. **The interception window is the gap between detection and impact.** When interception succeeds, it occurs well before the impact time. When it fails, the target reaches the city. This gap is the decision time available to the defense. - -4. **The interception rate depends strongly on geometry.** Approaches from directions where the drones are well-positioned in the approach corridor have higher interception rates. Approaches from directions where the drones are on the opposite side of the city fail. - -5. **Altitude matters.** Higher cruise altitudes give the drones more time to climb, but also increase the distance they must cover. The optimal altitude depends on the approach geometry. - -## Why the Rates Are Realistic - -The per-preset interception rates reflect the fundamental physics of a slower defender (100 m/s drones) vs. faster or equal-speed attackers: - -- A slow target (30–50 m/s) is easily caught — the drones have ample time to close the gap, so interception is near 100%. -- A mid-speed jet target (150 m/s) outruns part of the pursuit; only favorable geometries allow a timely intercept, giving ~68%. -- A fast sea-skimming cruise missile (300 m/s) is hard to catch, especially at low altitude where climb time hurts; ~36%. -- A very fast high-altitude ballistic re-entry (800 m/s) is far beyond the drones' capability; 0%. - -This is consistent with real-world observations that drone-vs-drone interception is challenging against faster targets, and that the interception rate depends heavily on the target's speed, altitude, approach direction, and the positioning of the defenders. - -## Files - -| File | Description | -|------|-------------| -| `defense_sim.py` | Python simulation with proper physics and projectile presets | -| `test_defense_sim.py` | Validation test suite (11 tests) | -| `defense_sim.html` | Interactive HTML visualization with preset dropdown | -| `montecarlo_stats.json` | Monte Carlo results (100 trials per preset) | - -## Running the Simulation - -```bash -# Run the Python simulation (runs all presets) -python3 defense_sim.py - -# Run the validation tests -python3 test_defense_sim.py - -# Open the HTML viewer in a browser (serve over HTTP for the stats table) -python3 -m http.server 8000 -# then open http://localhost:8000/defense_sim.html -``` - -### Selecting a Projectile Preset - -- **In the HTML:** use the **Projectile Preset** dropdown at the top of the Attack Parameters panel. Selecting a preset prefills all attack parameters (start distance, speed, cruise altitude band, descent start, terminal altitude) and highlights that preset's row in the stats table. Choose **Custom** to set all parameters manually. -- **In Python:** pass `preset='shahed-238'` (or any preset name) to `run_simulation()` or `monte_carlo()`. Omit it to use the default (`shahed-238`). - -## References - -1. CSIS Missile Threat Project - Shahed-238: https://missilethreat.csis.org/missile/shahed-238/ -2. BattlePolicy - Shahed-238: https://www.battlepolicy.com/shahed-238/ -3. Wikipedia - HESA Shahed 136: https://en.wikipedia.org/wiki/HESA_Shahed_136 -4. drone-warfare.com - Shahed-136 and Geran variants: https://drone-warfare.com/research/shahed-136/ -5. AERIS-10 radar: 10.5 GHz X-band FMCW phased array, 20 km range diff --git a/Licence b/Licence deleted file mode 100644 index 53167e5..0000000 --- a/Licence +++ /dev/null @@ -1,154 +0,0 @@ -CERN Open Hardware Licence Version 2 - Permissive - -Preamble - -CERN has developed this licence to promote collaboration among -hardware designers and to provide a legal tool for the dissemination -of hardware designs. The CERN Open Hardware Licence Version 2 is -available in two variants: Weakly Reciprocal (CERN-OHL-W) and -Permissive (CERN-OHL-P). The CERN-OHL-P is for you if you want to -maximise the ability of people to use your hardware design -including for use in commercial applications with a minimum of -obligations. It is a continuation of the CERN Open Hardware Licence -version 1 (but with a new structure) and is focused more narrowly -on the design itself and what you must do to give proper credit and -to allow others to build and modify the design. - -Please see the CERN-OHL version 2 family page (www.ohwr.org/cernohl) -for more information. - -Terms and conditions - -1. Definitions - -In this Licence, the following terms have the following meanings: - -“Additive” means something you add to the Design that was not part -of it when it was first published by the Licensor. - -“Design” means the design documentation for the hardware that is -licensed under this Licence, in any format or medium. It may -include both the Hardware Description and the Modifications. - -“Documentation” means all the materials that are provided by the -Licensor or any Contributor to describe the Design, including -schematics, netlists, PCB layout files, bills of materials, -drawings, specifications, and the like, and also includes the -Modifications. - -“Hardware” means any physical device that embodies the Design or -any part thereof, in any form. - -“Hardware Description” means the files that specify the Hardware in -a form that can be read by a computer and that, when used -appropriately, can be used to fabricate Hardware, for example in -whole or in part. - -“Licence” means this licence (the CERN-OHL-P). - -“Licensor” means the person or entity that first publishes the -Design under the terms of this Licence. - -“Modification” means any change to the Design, including changes to -the Hardware Description. - -“Product” means either an unchanged Design or a Design with -Modifications, that is offered for sale, or otherwise made -available for commercial use, whether as Hardware or in other forms. - -“Source” means the format of the Design that is preferred for -making Modifications, including all the files that are provided for -that purpose. - -“You” means any person or entity that exercises any right under -this Licence. - -2. What this Licence covers - -The Licensor grants you a worldwide, royalty-free, non-exclusive, -perpetual licence to: - -a) use the Design and any associated Documentation, -b) make Modifications, -c) communicate the Design and any Documentation, including by - making it available for copying and modification, -d) manufacture and distribute Hardware that implements the Design - or any part thereof, -e) sell Products, and -f) otherwise deal in the Design or any part thereof, - -all in each case subject to the conditions set out in this Licence. - -3. Conditions - -3.1. Availability of Source - -The Design and any Documentation that is made available under this -Licence must be made available in Source format. If the Design is -available in a format that is not Source, you must also make a -version of the Design in Source format available, and you must -inform others of how to obtain it. - -3.2. Retention of copyright and other notices - -You must retain all copyright and other notices that appear in the -Design or Documentation. - -3.3. Notice of Modifications - -If you make Modifications, you must include a notice in any -Distribution of the Design or Documentation, stating that -Modifications have been made, by whom, and in what they consist. - -3.4. Distribution of Modifications - -If you distribute any Design or Documentation, whether unchanged or -with Modifications, you must distribute it under this Licence, and -you must inform the recipient that the Design or Documentation is -licensed under this Licence. - -3.5. No implicit approval - -The Licensor shall not be taken to have approved any Modifications -unless the Licessor expressly approves them in writing. - -4. Disclaimer of warranty - -THE DESIGN AND ANY DOCUMENTATION IS PROVIDED "AS IS" AND THE -LICENSOR MAKES NO WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, -NON-INFRINGEMENT, TITLE, AND FITNESS FOR A PARTICULAR PURPOSE. THE -DESIGN MAY CONTAIN DESIGN DEFECTS OR ERRORS THAT MAKE IT -UNSUITABLE FOR USE IN CERTAIN APPLICATIONS. THE ENTIRE RISK AS TO -ITS QUALITY AND PERFORMANCE REMAINS WITH YOU. - -5. Limitation of liability - -TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL THE LICENSOR -BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION -LOST PROFITS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR ANY -OTHER LOSSES ARISING OUT OF THE USE OF THE DESIGN OR ANY -DOCUMENTATION, HOWEVER CAUSED, WHETHER UNDER THEORY OF CONTRACT, -TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY, OR OTHERWISE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -6. Termination - -This Licence is perpetual except that if you fail to comply with -its terms, your rights under this Licence will terminate immediately. -If you bring or defend any litigation or other claim alleging that -the Design or any part thereof infringes any intellectual property -right, all your rights under this Licence granted by the Licensor -will terminate forty-five days after you bring or defend such claim. - -7. General - -This Licence shall be governed by the laws of the country of the -Licensor, without reference to its conflict of laws provisions. -If any part of this Licence is held to be invalid or unenforceable, -the remaining parts shall remain in full force and effect. - ---------------------------------------------------------------------- - -CERN-OHL-P is a variant of the CERN-OHL family. For more information -see www.ohwr.org/cernohl. diff --git a/README.md b/README.md index a2ba040..6f15582 100644 --- a/README.md +++ b/README.md @@ -1,260 +1,55 @@ -[![GitHub stars](https://img.shields.io/github/stars/NawfalMotii79/PLFM_RADAR?style=social)](https://github.com/NawfalMotii79/PLFM_RADAR/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/NawfalMotii79/PLFM_RADAR?style=social)](https://github.com/NawfalMotii79/PLFM_RADAR/network/members) -[![GitHub watchers](https://img.shields.io/github/watchers/NawfalMotii79/PLFM_RADAR?style=social)](https://github.com/NawfalMotii79/PLFM_RADAR/watchers) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Hardware: CERN-OHL-P](https://img.shields.io/badge/Hardware-CERN--OHL--P-blue.svg)](https://ohwr.org/cern_ohl_p_v2.txt) +# AERIS-10 -# AERIS-10: Open Source Pulse Linear Frequency Modulated Phased Array Radar +10.5 GHz pulse linear-FM phased-array radar, with Overwatch beside the hardware design. -[![Hardware: CERN-OHL-P](https://img.shields.io/badge/Hardware-CERN--OHL--P-blue.svg)](https://ohwr.org/cern_ohl_p_v2.txt) -[![Software: MIT](https://img.shields.io/badge/Software-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Status: Alpha](https://img.shields.io/badge/Status-Alpha-orange)](https://github.com/NawfalMotii79/PLFM_RADAR) -[![Features: Work in Progress](https://img.shields.io/badge/Features-Work_in_Progress-yellow)](https://github.com/NawfalMotii79/PLFM_RADAR/issues) -[![Frequency: 10.5GHz](https://img.shields.io/badge/Frequency-10.5GHz-blue)](https://github.com/NawfalMotii79/PLFM_RADAR) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/NawfalMotii79/PLFM_RADAR/pulls) +| | | +|---|---| +| [simulation/](simulation/) | Overwatch. Physics, radar model, and the operator view. | +| [schematics/](schematics/) | Board schematics, stack-up, and production Gerbers. | +| [parts/parts-list.csv](parts/parts-list.csv) | Parts list taken from the production bills of materials. | +| [parts/cost.md](parts/cost.md) | Cost: the bills of materials do not contain prices. | +## Radar -AERIS-10 is an open-source, low-cost 10.5 GHz phased array radar system featuring Pulse Linear Frequency Modulated (LFM) modulation. Available in two versions (3km and 20km range), it's designed for researchers, drone developers, and serious SDR enthusiasts who want to explore and experiment with phased array radar technology. +Two builds share the signal chain. -![AERIS-10 Antenna Array](https://raw.githubusercontent.com/NawfalMotii79/PLFM_RADAR/main/8_Utils/Antenna_Array.jpg) +- **AERIS-10N**, about 3 km, 8×16 patch array. +- **AERIS-10X**, about 20 km, 32×16 dielectric-filled slotted waveguide, plus a 10 W QPA2962 stage on each of 16 amplifier boards. -## 📡 Overview +The array steers elevation electronically over ±45°. Azimuth on the prototype is a stepper. Carrier is 10.5 GHz. The FPGA does chirp generation, pulse compression, Doppler, MTI, and CFAR. An STM32 sequences power, clocks, phase shifters, and the GPS/IMU. -The AERIS-10 project aims to democratize radar technology by providing a fully open-source, modular, and hackable radar system. Whether you're a university researcher, a drone startup, or an advanced maker, AERIS-10 offers a platform for experimenting with beamforming, pulse compression, Doppler processing, and target tracking. +![Antenna array](hardware/mechanical/Antenna_Array.jpg) -## 🔬 Key Features +![System diagram](hardware/diagrams/RADAR_V6_V2.png) -- **Open Source Hardware & Software** - Complete schematics, PCB layouts, firmware, and software available -- **Dual Version Availability**: - - **AERIS-10N (Nexus)**: 3km range with 8x16 patch antenna array - - **AERIS-10E (Extended)**: 20km range with 32x16 dielectric-filled slotted waveguide array -- **Full Electronic Beam Steering** - ±45° electronic steering in elevation and azimuth -- **Advanced Signal Processing** - On-board FPGA handles pulse compression, Doppler FFT, MTI, and CFAR -- **Python GUI** - User-friendly interface with map integration -- **GPS/IMU Integration** - Real-time position and attitude correction -- **Modular Design** - Separate power management, frequency synthesis, and RF boards +### Where the rest of the design lives -## 🏗️ System Architecture +| Path | Contents | +|---|---| +| `schematics/4_6_Schematics/` | Main board, power board, frequency synthesizer, power amplifier, antennas | +| `schematics/4_7_Production Files/` | Gerbers, pick-and-place, and the original board bills of materials | +| `parts/datasheets/` | Component datasheets | +| `hardware/diagrams/` | Functional diagram | +| `hardware/power/` | Power-rail and sequencing sheet | +| `hardware/description/` | Project description | +| `hardware/rf-simulations/` | Antenna, filter, and waveguide studies. These are circuit simulations, not Overwatch. | +| `hardware/mechanical/` | Enclosure and waveguide drawings | +| `hardware/application-notes/` | ADAR1000 user guide | +| `firmware/` | STM32, FPGA, and the radar GUI | +| `docs/` | Architecture notes, bring-up, and reports | -![AERIS-10 System Diagram](https://raw.githubusercontent.com/NawfalMotii79/PLFM_RADAR/main/8_Utils/RADAR_V6_V2.png) +## Overwatch -### Hardware Components +From the repository root: -The AERIS-10 main sub-systems are: +```bash +cd simulation +python -m pip install -e '.[server,dev,flight,performance]' +python -m defense_sim.cli --steps 500 --seed 7 +``` -- **Power Management Board** - Supplies all necessary voltage levels to the electronics components with proper filtering and sequencing (sequencing ensured by the microcontroller) +The earlier simulator, the standalone scripts and the single-page viewer that used to sit in the repository root, has been removed. -- **Frequency Synthesizer Board** - Uses a high-performance Low Jitter Clock Generator (AD9523-1) that supplies phase-aligned clock references for: - - RX and TX Frequency Synthesizers (ADF4382) - - DAC - - ADC - - FPGA +## Contact -- **Main Board** containing: - - **DAC** - Generates the RADAR Chirps - - **2x Microwave Mixers (LTC5552)** - For up-conversion and IF-down-conversion - - **4x 4-Channel Phase Shifters (ADAR1000)** - For RX and TX chain beamforming - - **16x Front End Chips (ADTR1107)** - Used for both Low Noise Amplifying (RX) and Power Amplifying (TX) stages - - **XC7A50T FPGA** - Handles RADAR Signal Processing on the upstream FTG256 board: - - PLFM Chirps generation via the DAC - - Raw ADC data read - - Hybrid Automatic Gain Control (AGC) — cross-layer FPGA/STM32/GUI loop - - I/Q Baseband Down-Conversion - - Decimation - - Filtering - - Forward FFT - - Pulse Compression - - Doppler, MTI and CFAR processing - - USB Interface - - **STM32F746xx Microcontroller** - Used for: - - Power-up and power-down sequencing (see Power Management Excel File) - - FPGA communication - - Setup and Interface with: - - Clock Generator (AD9523-1) - - 2x Frequency Synthesizers (ADF4382) - - 4x 4-Channel Phase Shifters (ADAR1000) for RADAR pulse sequencing - - 2x ADS7830 8-channel I²C ADCs (Main Board, U88 @ 0x48 / U89 @ 0x4A) for 16x Idq measurement, one per PA channel, each sensed through a 5 mΩ shunt on the PA board and an INA241A3 current-sense amplifier (x50) on the Main Board - - 2x DAC5578 8-channel I²C DACs (Main Board, U7 @ 0x48 / U69 @ 0x49) for 16x Vg control, one per PA channel; closed-loop calibrated at boot to the target Idq - - GPS module (UM982) for GUI map centering and per-detection position tagging - - GY-85 IMU for pitch/roll correction of target coordinates - - BMP180 Barometer - - Stepper Motor - - 1x ADS7830 8-channel I²C ADC (Main Board, U10) reading 8 thermistors for thermal monitoring; a single GPIO (EN_DIS_COOLING) switches the cooling fans on when any channel exceeds the threshold - - RF switches - -- **16x Power Amplifier Boards** - Used only for AERIS-10E version, featuring 10Watt QPA2962 GaN amplifier for extended range - -- **Antenna Arrays**: - - **AERIS-10N (Nexus)** - 8x16 patch antenna array - - **AERIS-10X (Extended)** - 32x16 dielectric-filled slotted waveguide antenna array - -- **Miscellaneous Components**: - - Slip-Ring - - Stepper Motor and drivers - - Cooling Fans - - Enclosure - -### Processing Pipeline - -1. **Waveform Generation** - DAC creates LFM chirps -2. **Up/Down Conversion** - LTC5552 mixers handle frequency translation -3. **Beam Steering** - ADAR1000 phase shifters control 16 elements -4. **Signal Processing (FPGA)**: - - Raw ADC data capture - - I/Q baseband down-conversion - - Decimation & filtering (CIC/FIR) - - Pulse compression - - Doppler FFT processing - - MTI & CFAR detection -5. **System Management (STM32)**: - - Power sequencing - - Peripheral configuration - - GPS/IMU integration - - Stepper motor control -6. **Visualization (Python GUI)**: - - Real-time target plotting - - Map integration - - Radar control interface - -![AERIS-10 Dashboard](https://raw.githubusercontent.com/NawfalMotii79/PLFM_RADAR/main/8_Utils/GUI_V6.gif) - - -## 📊 Technical Specifications - -| Parameter | AERIS-10N (Nexus) | AERIS-10X (Extended) | -|-----------|-------------------|----------------------| -| **Frequency** | 10.5 GHz | 10.5 GHz | -| **Max Range** | 3 km | 20 km | -| **Antenna** | 8x16 Patch Array | 32x16 Slotted Waveguide | -| **Beam Steering** | Electronic (±45°) | Electronic (±45°) | -| **Mechanical Scan** | 360° (stepper motor) | 360° (stepper motor) | -| **Output Power** | ~1W×16 | 10W×16 (GaN amplifier) | -| **Processing** | FPGA + STM32 | FPGA + STM32 | - -## 🚀 Getting Started - -### 🧹 Repository File Placement Policy - -To keep the repository root clean and make artifacts easy to find, place generated files in the following locations: - -- **Published reports (tracked, GitHub Pages):** `docs/` - - Example: `docs/AERIS_Simulation_Report_v2.pdf` -- **Simulation-generated outputs (local, gitignored):** `5_Simulations/generated/` - - Plots, scenario outputs, temporary analysis directories -- **FPGA/Vivado generated artifacts (local, gitignored):** `9_Firmware/9_2_FPGA/reports/` - - VCD/VVP dumps, temporary CSVs, local report snapshots -- **Reusable FPGA automation scripts (tracked):** `9_Firmware/9_2_FPGA/scripts/` - - TCL flows, helper scripts used by build/bring-up - -**Do not leave generated artifacts in the repository root.** - -### Prerequisites - -- Basic understanding of radar principles -- Experience with PCB assembly (for hardware build) -- Python 3.8+ for the GUI software -- FPGA development tools (Vivado) for signal processing modifications - -### Hardware Assembly - -1. **Order PCBs**: Production outputs are under `/4_Schematics and Boards Layout/4_7_Production Files` -2. **Source Components**: BOM/CPL files are co-located under `/4_Schematics and Boards Layout/4_7_Production Files` -3. **Assembly**: Use the schematics in `/4_Schematics and Boards Layout/4_6_Schematics` together with the production outputs above; a standalone assembly guide is not currently tracked -4. **Antenna**: Choose appropriate array files for your target variant -5. **Enclosure**: Mechanical drawings currently live in `/8_Utils/Mechanical_Drawings` - -## 📜 License - -This project is open-source but uses **different licenses for hardware and software** to ensure proper legal coverage. - -### Hardware Documentation -The hardware design files—including: -- Schematics and PCB layouts (in `/4_Schematics and Boards Layout`) -- Bill of Materials (BOM) files -- Gerber files and manufacturing outputs -- Mechanical drawings and enclosure designs - -are licensed under the **CERN Open Hardware Licence Version 2 – Permissive (CERN-OHL-P)** . - -This is a hardware-specific license that: -- ✅ Clearly defines "Hardware," "Documentation," and "Products" -- ✅ Includes explicit patent protection for contributors and users -- ✅ Provides stronger liability limitations (important for high-power RF) -- ✅ Aligns with professional open-hardware standards (CERN, OSHWA) - -You may use, modify, and sell products based on these designs, provided you: -- Maintain the original copyright notices -- Distribute any modified designs under the same license -- Make your modifications available in Source format - -### Software and Firmware -The software components—including: -- FPGA code (VHDL/Verilog in `/9_Firmware`) -- Microcontroller firmware (STM32) -- Python GUI and utilities - -remain under the **MIT License** for maximum flexibility. - -### Full License Texts -- The complete CERN-OHL-P license text is in the `LICENSE` file -- MIT license terms apply to software where not otherwise specified - -### Why This Change? -Originally, the entire project used the MIT license. The community (special thanks to gmaynez!) pointed out that MIT lacks legal protections needed for physical hardware. The switch to CERN-OHL-P ensures the project is properly protected while maintaining the same permissive spirit. - -## 📚 Documentation - -Comprehensive documentation is available in the `/docs` folder and served via GitHub Pages at [https://NawfalMotii79.github.io/PLFM_RADAR/docs/](https://NawfalMotii79.github.io/PLFM_RADAR/docs/): - -- [System Architecture](/docs/architecture.html) -- [Implementation Log](/docs/implementation-log.html) -- [Hardware Bring-Up Guide](/docs/bring-up.html) -- [Test Reports](/docs/reports.html) -- [Release Notes](/docs/release-notes.html) - -## 🤝 Contributing - -We welcome contributions! Please see our [Contributing Guidelines](/CONTRIBUTING.md) for details on repo layout, branch workflow, and basic PR checks. - -Areas where help is especially appreciated: -- **RF Engineers**: Review designs, optimize antenna performance -- **FPGA Developers**: Optimize signal processing pipeline -- **Software Developers**: Enhance Python GUI and SDK -- **Beta Testers**: University researchers, drone startups, advanced makers - -## 📞 Contact & Collaboration - -I welcome serious inquiries from researchers, engineers, and potential collaborators. However, due to the high volume of interest in this project, please understand that I cannot guarantee a response to every message. - -- **Technical questions or bug reports**: Please [open a GitHub issue](https://github.com/NawfalMotii79/PLFM_RADAR/issues) so the whole community can benefit from the discussion. -- **Collaboration, licensing, or business inquiries**: 📧 nawfal.motii.33 [at] gmail [dot] com - -## 💰 Sponsors - -![PCBWay Sponsor Logo](https://raw.githubusercontent.com/NawfalMotii79/PLFM_RADAR/main/8_Utils/PCBWAY.jpg) - ---- - -**Star ⭐ this repository if you're interested in open-source radar technology!** - -*Note: This is an active development project. Some features are still in progress. Check the issues page for known limitations and upcoming features.* - -## 19,000 stars – Thank you - -This project started in a small workshop in Morocco. Today, 19,000 engineers on GitHub have starred it. - -I am genuinely humbled. - -**What this tells me:** - -- Open source radar matters -- Affordable sensing is needed -- Engineers want to build, not just buy - -Thank you to everyone who starred, forked, opened issues, submitted PRs, and shared this project. - -The work continues. - -**Nawfal Motii** -ABAC INDUSTRY -(http://www.abacindustry.com) +Nawfal Motii, ABAC INDUSTRY. Technical questions go through the project issue tracker. Collaboration and business inquiries: nawfal.motii.33 [at] gmail [dot] com. diff --git a/debug2.js b/debug2.js deleted file mode 100644 index 3b5dcf3..0000000 --- a/debug2.js +++ /dev/null @@ -1,57 +0,0 @@ -const fs = require('fs'); -const html = fs.readFileSync('defense_sim.html', 'utf8'); -const script = html.match(/ - - diff --git a/defense_sim.py b/defense_sim.py deleted file mode 100644 index 8d9db42..0000000 --- a/defense_sim.py +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/env python3 -""" -Generalized Projectile Defense Simulation -========================================== -Models a projectile/drone attack profile and defender radar/drone -intercept with proper physics and error propagation. - -Supports multiple projectile types via presets: -- Shahed-136 (Geran-2): prop, ~50 m/s, low altitude -- Shahed-238 (Geran-3): jet, ~150 m/s, 1-2 km cruise (default) -- Cruise Missile: ~300 m/s, sea-skimming -- Ballistic (Re-entry): ~800 m/s, high altitude entry -- Small UAS / Prop Drone: ~30 m/s, low altitude - -Defender: -- 8 AERIS-10 radars (20 km range, ±20 m single-shot accuracy) -- 24 interceptor drones (100 m/s, IR homing within 5 km) -""" - -import numpy as np -import json -import sys - -# ============================================================================= -# Projectile Presets -# ============================================================================= -# Each preset defines the attack profile: -# start_dist: km - distance from city center at launch -# speed: m/s - cruise speed -# cruise_alt_min / cruise_alt_max: m - cruise altitude range (randomized within) -# descent_start: km - distance from target at which descent begins -# terminal_alt: m - altitude at impact -PRESETS = { - 'shahed-136': {'start_dist': 30, 'speed': 50, 'cruise_alt_min': 100, 'cruise_alt_max': 300, 'descent_start': 5, 'terminal_alt': 0}, - 'shahed-238': {'start_dist': 35, 'speed': 150, 'cruise_alt_min': 1000, 'cruise_alt_max': 2000, 'descent_start': 8, 'terminal_alt': 200}, - 'cruise-missile': {'start_dist': 50, 'speed': 300, 'cruise_alt_min': 50, 'cruise_alt_max': 150, 'descent_start': 5, 'terminal_alt': 0}, - 'ballistic-reentry':{'start_dist': 100, 'speed': 800, 'cruise_alt_min': 60000, 'cruise_alt_max': 80000, 'descent_start': 40, 'terminal_alt': 0}, - 'prop-drone': {'start_dist': 15, 'speed': 30, 'cruise_alt_min': 100, 'cruise_alt_max': 300, 'descent_start': 3, 'terminal_alt': 0}, -} -DEFAULT_PRESET = 'shahed-238' - - -def get_preset(name=None): - """Return the preset dict for a given name, or the default.""" - if name is None: - name = DEFAULT_PRESET - return PRESETS.get(name, PRESETS[DEFAULT_PRESET]) - -# ============================================================================= -# Defender constants -# ============================================================================= - -# Radar parameters -RADAR_RANGE = 20000.0 # m -RADAR_ERROR_1SIGMA = 20.0 # m (single measurement, 1 sigma) -NUM_RADARS = 8 - -# Drone parameters -DRONE_SPEED = 100.0 # m/s -DRONE_MAX_ALT = 4000.0 # m -DRONE_DEFENSE_LINE = 8000.0 # m from city center -IR_RANGE = 5000.0 # m -IR_ERROR_1SIGMA = 3.0 # m -NUM_DRONES = 24 -CITY_RADIUS = 10000.0 # m - -# Simulation -DT = 0.5 # s (time step, coarser for speed) -SIM_DURATION = 400.0 # s - -# ============================================================================= -# Flight Profile -# ============================================================================= - -def target_trajectory(start_pos, target_pos, cruise_alt, speed, descent_start, terminal_alt): - """ - Generate a realistic projectile flight trajectory. - - Cruise at cruise_alt until `descent_start` distance from target - - Gradual descent to `terminal_alt` over the remaining distance - - Straight horizontal path (simplified for 2D projection) - - descent_start: distance (m) from target at which descent begins - terminal_alt: altitude (m) at impact - - Returns: list of (x, y, z, t) tuples - """ - start_pos = np.array(start_pos) - target_pos = np.array(target_pos) - - # Horizontal direction - dx = target_pos[0] - start_pos[0] - dy = target_pos[1] - start_pos[1] - horiz_dist = np.sqrt(dx**2 + dy**2) - - if horiz_dist < 1e-6: - return [] - - dir_x = dx / horiz_dist - dir_y = dy / horiz_dist - - # Descent begins at `descent_start` distance from target - # So descent begins at (horiz_dist - descent_start) from start - descent_start_dist = max(0.0, horiz_dist - descent_start) - - # Descent distance (clamped to available distance) - descent_dist = max(0.0, min(descent_start, horiz_dist)) - - # Total duration - total_duration = horiz_dist / speed - - trajectory = [] - t = 0.0 - - while t <= total_duration + DT: - # Distance traveled - dist_traveled = speed * t - - # Determine altitude - if descent_dist <= 0 or dist_traveled < descent_start_dist: - # Cruise phase - z = cruise_alt - else: - # Descent phase: linear interpolation from cruise_alt to terminal_alt - descent_progress = min(1.0, (dist_traveled - descent_start_dist) / descent_dist) - z = cruise_alt + (terminal_alt - cruise_alt) * descent_progress - - # Horizontal position - x = start_pos[0] + dir_x * dist_traveled - y = start_pos[1] + dir_y * dist_traveled - - trajectory.append((x, y, z, t)) - t += DT - - return trajectory - -# ============================================================================= -# Radar Detection Model -# ============================================================================= - -def radar_positions(num_radars, city_radius): - """Generate radar positions on a circle around the city.""" - positions = [] - for i in range(num_radars): - angle = 2 * np.pi * i / num_radars - dist = city_radius + 2000 # 2 km outside city - x = dist * np.cos(angle) - y = dist * np.sin(angle) - positions.append(np.array([x, y, 0.0])) - return positions - -def drone_positions(num_drones, city_radius, defense_line): - """Generate drone positions on a circle around the city.""" - positions = [] - for i in range(num_drones): - angle = 2 * np.pi * i / num_drones - dist = city_radius + defense_line - x = dist * np.cos(angle) - y = dist * np.sin(angle) - positions.append({ - 'pos': np.array([x, y, 0.0]), - 'state': 'waiting', - 'index': i - }) - return positions - -def detect_from_radars(pos, radar_pos_list, radar_range, rng): - """ - Detect target position from all radars in range. - Returns list of (range, azimuth, elevation, radar_index) and estimated 3D position. - """ - detections = [] - for i, rpos in enumerate(radar_pos_list): - dist = np.linalg.norm(pos - rpos) - if dist < radar_range: - # Add measurement noise - range_meas = dist + rng.normal(0, RADAR_ERROR_1SIGMA) - azimuth_true = np.arctan2(pos[1] - rpos[1], pos[0] - rpos[0]) - elevation_true = np.arctan2(pos[2] - rpos[2], np.sqrt((pos[0]-rpos[0])**2 + (pos[1]-rpos[1])**2)) - - azimuth_meas = azimuth_true + rng.normal(0, RADAR_ERROR_1SIGMA / max(100, dist)) - elevation_meas = elevation_true + rng.normal(0, RADAR_ERROR_1SIGMA / max(100, dist)) - - detections.append({ - 'range': range_meas, - 'azimuth': azimuth_meas, - 'elevation': elevation_meas, - 'radar_index': i - }) - - return detections - -def estimate_position_3d(detections, radar_pos_list, rng): - """ - Estimate 3D position from multiple radar detections. - Each radar provides azimuth, elevation, and range, which together define a 3D point. - The estimated position is the least-squares fit of these 3D point estimates. - Returns (x, y, z) estimate and covariance. - """ - if len(detections) < 2: - return None, None - - # Each radar's bearing + range defines a 3D point estimate - estimates = [] - for det in detections: - ri = radar_pos_list[det['radar_index']] - az = det['azimuth'] - el = det['elevation'] - r = det['range'] - - # Convert bearing + range to 3D offset from radar - dx = r * np.cos(el) * np.cos(az) - dy = r * np.cos(el) * np.sin(az) - dz = r * np.sin(el) - - p_est = ri + np.array([dx, dy, dz]) - estimates.append(p_est) - - # Least-squares estimate is the mean of the point estimates - p = np.mean(estimates, axis=0) - - # Estimate covariance from the spread of estimates - if len(estimates) > 1: - spread = np.std(np.array(estimates), axis=0) - cov = np.diag(spread**2) - else: - sigma_pos = RADAR_ERROR_1SIGMA - cov = np.eye(3) * sigma_pos**2 - - return p, cov - -# ============================================================================= -# Trajectory Estimation (Linear Regression) -# ============================================================================= - -def estimate_trajectory(observations, rng=None): - """ - Estimate trajectory (velocity) from a series of position observations. - Each observation is (x, y, z, t). - Returns (vx, vy, vz) and covariance. - """ - if len(observations) < 2: - return None, None - - times = np.array([o[3] for o in observations]) - xs = np.array([o[0] for o in observations]) - ys = np.array([o[1] for o in observations]) - zs = np.array([o[2] for o in observations]) - - n = len(observations) - - # Linear regression for each axis: pos = pos0 + vel * t - vel = np.zeros(3) - pos0 = np.zeros(3) - for axis in range(3): - pos = np.array([o[axis] for o in observations]) - if n >= 2: - # Least squares fit: pos = pos0 + vel*t - A = np.vstack([np.ones(n), times]).T - coeffs, _, _, _ = np.linalg.lstsq(A, pos, rcond=None) - pos0[axis] = coeffs[0] - vel[axis] = coeffs[1] - - # Covariance estimate - # For linear regression, Var(v) = sigma^2 / Sxx where Sxx = sum((t - t_mean)^2) - t_mean = np.mean(times) - Sxx = np.sum((times - t_mean)**2) - sigma_vel = RADAR_ERROR_1SIGMA / np.sqrt(Sxx) if Sxx > 0 else RADAR_ERROR_1SIGMA - cov = np.eye(3) * sigma_vel**2 - - return vel, cov - -# ============================================================================= -# Drone Intercept Logic -# ============================================================================= - -def compute_intercept_point(drone_pos, target_pos, target_vel, drone_speed): - """ - Compute the intercept point for a drone chasing a moving target in 3D. - Solves the classic pursuer-target problem: - |drone_pos + v_d*t - target_pos - v_s*t| = 0 - where v_d = drone_speed * unit_vector(direction to intercept) - - This works even when the drone is slower than the target, - as long as the drone is positioned close enough to the intercept path. - - Returns: intercept point (3D) and estimated time - """ - drone_pos = np.array(drone_pos, dtype=float) - target_pos = np.array(target_pos, dtype=float) - target_vel = np.array(target_vel, dtype=float) - - # Relative position and velocity - rel_pos = target_pos - drone_pos # where target is relative to drone - rel_vel = target_vel # relative velocity (drone direction is variable) - - # We need to find a direction d (unit vector) and time t such that: - # drone_speed * t * d = rel_pos + target_vel * t - # => d = (rel_pos + target_vel * t) / (drone_speed * t) - # And |d| = 1, so: - # |rel_pos + target_vel * t| = drone_speed * t - - # Let's expand: - # |rel_pos + v_s*t|^2 = v_d^2 * t^2 - # |rel_pos|^2 + 2*t*(rel_pos·v_s) + t^2*(v_s·v_s) = v_d^2 * t^2 - # |rel_pos|^2 + 2*t*(rel_pos·v_s) + t^2*(|v_s|^2 - v_d^2) = 0 - - a = np.dot(target_vel, target_vel) - drone_speed**2 - b = 2 * np.dot(rel_pos, target_vel) - c = np.dot(rel_pos, rel_pos) - - # Solve quadratic: a*t^2 + b*t + c = 0 - discriminant = b*b - 4*a*c - - if a == 0: - # Linear equation: b*t + c = 0 - if abs(b) < 1e-10: - # No solution - t = np.linalg.norm(rel_pos) / drone_speed - intercept = drone_pos + rel_pos - return intercept, t - t = -c / b - if t <= 0: - t = np.linalg.norm(rel_pos) / drone_speed - intercept = drone_pos + rel_pos - return intercept, t - target_future = target_pos + target_vel * t - intercept = target_future - return intercept, t - - if discriminant < 0: - # No intercept possible with this geometry - # Fallback: aim at current position - t = np.linalg.norm(rel_pos) / drone_speed - intercept = drone_pos + rel_pos - return intercept, t - - # Compute both roots, pick the smallest positive one - sqrt_disc = np.sqrt(discriminant) - t_candidates = [ - (-b + sqrt_disc) / (2 * a), - (-b - sqrt_disc) / (2 * a) - ] - - positive_roots = [t for t in t_candidates if t > 0] - - if not positive_roots: - # No valid positive intercept - t = np.linalg.norm(rel_pos) / drone_speed - intercept = drone_pos + rel_pos - return intercept, t - - # The smallest positive root is the earliest intercept - t = min(positive_roots) - - # Intercept point: where target will be at time t - target_future = target_pos + target_vel * t - intercept = target_future - - return intercept, t - -def drone_trajectory(drone_start, intercept_point, drone_speed): - """ - Generate a smooth 3D trajectory for the drone from start to intercept. - Simple: linear interpolation with altitude management. - """ - drone_start = np.array(drone_start) - intercept = np.array(intercept_point) - - total_dist = np.linalg.norm(intercept - drone_start) - duration = total_dist / drone_speed - - # Generate waypoints - num_steps = max(2, int(duration / DT)) - trajectory = [] - for i in range(num_steps + 1): - frac = i / num_steps - pos = drone_start + frac * (intercept - drone_start) - t = i * DT - trajectory.append((pos[0], pos[1], pos[2], t)) - - return trajectory - -# ============================================================================= -# Main Simulation -# ============================================================================= - -def run_simulation(seed=None, debug=False, preset=None): - """Run one full simulation and return results. - preset: name of a projectile preset (or None for default). - """ - rng = np.random.default_rng(seed) - preset_name = preset if preset is not None else DEFAULT_PRESET - preset_data = get_preset(preset) - - # Attack parameters from preset (with some randomization) - start_dist = preset_data['start_dist'] * 1000.0 * rng.uniform(0.9, 1.1) # m, ±10% - start_angle = rng.uniform(0, 2 * np.pi) - target_angle = rng.uniform(0, 2 * np.pi) - target_dist = rng.uniform(0, CITY_RADIUS * 0.8) - - start_pos = np.array([ - start_dist * np.cos(start_angle), - start_dist * np.sin(start_angle), - 0 - ]) - - terminal_alt = preset_data['terminal_alt'] - target_pos = np.array([ - target_dist * np.cos(target_angle), - target_dist * np.sin(target_angle), - terminal_alt # terminal altitude - ]) - - cruise_alt = rng.uniform(preset_data['cruise_alt_min'], preset_data['cruise_alt_max']) - speed = preset_data['speed'] - descent_start = preset_data['descent_start'] * 1000.0 # m - - if debug: - print(f" [DEBUG] preset={preset_data} start_dist={start_dist:.0f}m, cruise_alt={cruise_alt:.0f}m") - print(f" [DEBUG] start_pos={start_pos}, target_pos={target_pos}") - - # Generate trajectory - trajectory = target_trajectory(start_pos, target_pos, cruise_alt, speed, descent_start, terminal_alt) - if not trajectory: - return None - - # Setup radar and drones - radar_pos_list = radar_positions(NUM_RADARS, CITY_RADIUS) - drone_pos_list = drone_positions(NUM_DRONES, CITY_RADIUS, DRONE_DEFENSE_LINE) - - # Simulation state - time = 0.0 - detection_time = None - launched_drones = [] - collision = False - observations = [] - - # Pre-compute true target position at each time step - true_positions = {t: np.array([x, y, z]) for x, y, z, t in trajectory} - - def get_true_pos(t): - # Find closest trajectory point - times = sorted(true_positions.keys()) - # Binary search for closest - idx = np.searchsorted(times, t) - if idx >= len(times): - return true_positions[times[-1]] - if idx == 0: - return true_positions[times[0]] - # Choose closer of two adjacent - t1, t2 = times[idx-1], times[idx] - if abs(t - t1) < abs(t - t2): - return true_positions[t1] - return true_positions[t2] - - # Main loop - while time < SIM_DURATION and not collision: - true_pos = get_true_pos(time) - - # Check radar detection - detections = detect_from_radars(true_pos, radar_pos_list, RADAR_RANGE, rng) - active_radars = [d['radar_index'] for d in detections] - - if active_radars: - observations.append((true_pos[0], true_pos[1], true_pos[2], time)) - - # First detection triggers alert - if detection_time is None and len(observations) >= 3: - detection_time = time - - if debug: - print(f" [DEBUG] Detection at t={time:.1f}s, true_pos={true_pos}") - - # Estimate 3D position (only once at detection) - pos_est, cov = estimate_position_3d(detections, radar_pos_list, rng) - if pos_est is not None: - observations[-1] = (pos_est[0], pos_est[1], pos_est[2], time) - if debug: - print(f" [DEBUG] pos_est={pos_est}, true={true_pos}, err={np.linalg.norm(pos_est-true_pos):.1f}m") - - # Estimate trajectory (only once at detection) - vel_est, vel_cov = estimate_trajectory(observations, rng) - if vel_est is not None: - if debug: - print(f" [DEBUG] vel_est={vel_est}, true_vel approx={speed} m/s") - - # Compute time to impact for this trajectory - # Target distance to city center - target_horiz_dist = np.sqrt(true_pos[0]**2 + true_pos[1]**2) - speed_est = np.linalg.norm(vel_est) - t_to_impact = target_horiz_dist / speed_est if speed_est > 0 else float('inf') - - if debug: - print(f" [DEBUG] t_to_impact={t_to_impact:.1f}s, target_horiz_dist={target_horiz_dist:.0f}m") - - # Launch drones that can intercept before impact - drone_intercepts = [] - for i in range(NUM_DRONES): - drone_pos = drone_pos_list[i]['pos'] - intercept, t_int = compute_intercept_point( - drone_pos, true_pos, vel_est, DRONE_SPEED - ) - # Only viable if intercept happens before impact - if t_int < t_to_impact: - drone_intercepts.append((t_int, i, intercept)) - - drone_intercepts.sort(key=lambda x: x[0]) - launched_drones = [d[1] for d in drone_intercepts[:3]] - - if debug: - print(f" [DEBUG] viable drones: {len(drone_intercepts)}, launched: {launched_drones}") - for d in drone_intercepts[:3]: - print(f" [DEBUG] drone {d[1]} t_int={d[0]:.1f}s intercept=({d[2][0]:.0f},{d[2][1]:.0f},{d[2][2]:.0f})") - - # Compute intercept points - for d in drone_intercepts[:3]: - i = d[1] - drone_pos_list[i]['intercept'] = d[2] - drone_pos_list[i]['state'] = 'flying' - - # Update drones - if launched_drones: - # Re-target drones periodically (proportional navigation) - if detection_time is not None and (time - detection_time) % 5.0 < DT: - vel_est_new, _ = estimate_trajectory(observations, rng) - if vel_est_new is not None: - # Recompute intercept points for launched drones - for i in launched_drones: - drone = drone_pos_list[i] - if drone['state'] in ('flying', 'ir_tracking'): - intercept, t_int = compute_intercept_point( - drone['pos'], true_pos, vel_est_new, DRONE_SPEED - ) - drone['intercept'] = intercept - - for i in launched_drones: - drone = drone_pos_list[i] - if drone['state'] in ('flying', 'ir_tracking'): - intercept = drone.get('intercept') - if intercept is not None: - delta = intercept - drone['pos'] - dist = np.linalg.norm(delta) - if dist > 0.01: - step = DRONE_SPEED * DT - drone['pos'] = drone['pos'] + (delta / dist) * step - else: - drone['pos'] = intercept - - # Check IR range - target_dist_local = np.linalg.norm(true_pos - drone['pos']) - if drone['state'] == 'flying' and target_dist_local < IR_RANGE: - drone['state'] = 'ir_tracking' - if debug: - print(f" [DEBUG] t={time:.1f}s drone {i} -> IR tracking, dist={target_dist_local:.0f}m") - - # Check collision - if target_dist_local < 20.0: # 20 m kill radius - collision = True - if debug: - print(f" [DEBUG] COLLISION at t={time:.1f}s drone {i}") - break - elif debug and time % 10 < DT: - print(f" [DEBUG] t={time:.1f}s drone {i} pos=({drone['pos'][0]:.0f},{drone['pos'][1]:.0f},{drone['pos'][2]:.0f}), target=({true_pos[0]:.0f},{true_pos[1]:.0f},{true_pos[2]:.0f}), dist={target_dist_local:.0f}m") - - # Check if target reached city - horiz_dist = np.sqrt(true_pos[0]**2 + true_pos[1]**2) - if horiz_dist < CITY_RADIUS and not collision: - break - - time += DT - - # Calculate results - result = { - 'preset': preset_name, - 'start_dist': start_dist, - 'cruise_alt': cruise_alt, - 'speed': speed, - 'terminal_alt': terminal_alt, - 'detection_time': detection_time, - 'collision': collision, - 'time_of_collision': time if collision else None, - 'time_of_impact': time if not collision else None, - 'num_observations': len(observations), - 'launched_drones': launched_drones, - 'seed': seed - } - - return result - -# ============================================================================= -# Monte Carlo Validation -# ============================================================================= - -def monte_carlo(n_trials=100, seed_base=42, preset=None): - """Run Monte Carlo simulation and return statistics. - preset: name of a projectile preset (or None for default). - """ - results = [] - for i in range(n_trials): - result = run_simulation(seed=seed_base + i, preset=preset) - if result is not None: - results.append(result) - - if not results: - return None - - # Statistics - collisions = sum(1 for r in results if r['collision']) - detection_times = [r['detection_time'] for r in results if r['detection_time'] is not None] - collision_times = [r['time_of_collision'] for r in results if r['collision']] - impact_times = [r['time_of_impact'] for r in results if not r['collision']] - num_obs = [r['num_observations'] for r in results] - cruise_alts = [r['cruise_alt'] for r in results] - preset_name = results[0]['preset'] - - stats = { - 'preset': preset_name, - 'total_trials': len(results), - 'collisions': collisions, - 'interception_rate': collisions / len(results) * 100, - 'avg_detection_time': np.mean(detection_times) if detection_times else None, - 'avg_collision_time': np.mean(collision_times) if collision_times else None, - 'avg_impact_time': np.mean(impact_times) if impact_times else None, - 'avg_observations': np.mean(num_obs), - 'min_observations': np.min(num_obs), - 'max_observations': np.max(num_obs), - 'avg_cruise_alt': np.mean(cruise_alts), - 'min_cruise_alt': np.min(cruise_alts), - 'max_cruise_alt': np.max(cruise_alts), - } - - return stats, results - -# ============================================================================= -# Main -# ============================================================================= - -if __name__ == '__main__': - print("=" * 80) - print("Generalized Projectile Defense Simulation") - print("=" * 80) - print() - - # Run single simulation for demo (default preset) - print(f"Running single simulation (preset={DEFAULT_PRESET})...") - result = run_simulation(seed=42) - if result: - print(f" Preset: {result['preset']}") - print(f" Start distance: {result['start_dist']/1000:.1f} km") - print(f" Speed: {result['speed']:.0f} m/s") - print(f" Cruise altitude: {result['cruise_alt']:.0f} m") - print(f" Detection time: {result['detection_time']:.1f} s" if result['detection_time'] else " Detection time: N/A") - print(f" Collision: {'YES' if result['collision'] else 'NO'}") - if result['collision']: - print(f" Collision time: {result['time_of_collision']:.1f} s") - else: - print(f" Impact time: {result['time_of_impact']:.1f} s") - print(f" Observations: {result['num_observations']}") - print() - - # Run Monte Carlo for each preset - print("Running Monte Carlo (100 trials per preset)...") - all_stats = {} - for preset_name in PRESETS.keys(): - stats, results = monte_carlo(n_trials=100, seed_base=100, preset=preset_name) - if stats: - all_stats[preset_name] = stats - print(f" [{preset_name}]") - print(f" Interception rate: {stats['interception_rate']:.1f}%") - if stats['avg_detection_time']: - print(f" Avg detection time: {stats['avg_detection_time']:.1f} s") - if stats['avg_collision_time']: - print(f" Avg collision time: {stats['avg_collision_time']:.1f} s") - if stats['avg_impact_time']: - print(f" Avg impact time: {stats['avg_impact_time']:.1f} s") - print(f" Avg cruise altitude: {stats['avg_cruise_alt']:.0f} m") - print() - - # Save stats to JSON for the HTML viewer (per preset) - import json - json_stats = { - preset_name: { - 'total_trials': stats['total_trials'], - 'collisions': stats['collisions'], - 'interception_rate': stats['interception_rate'], - 'avg_detection_time': stats['avg_detection_time'], - 'avg_collision_time': stats['avg_collision_time'], - 'avg_impact_time': stats['avg_impact_time'], - 'avg_observations': stats['avg_observations'], - } - for preset_name, stats in all_stats.items() - } - with open('montecarlo_stats.json', 'w') as f: - json.dump(json_stats, f, indent=2) - print() - print("Stats saved to montecarlo_stats.json") - - print() - print("=" * 80) - print("Simulation complete") - print("=" * 80) diff --git a/defense_sim_v2/frontend/LICENSE b/defense_sim_v2/frontend/LICENSE deleted file mode 100644 index 670b1b3..0000000 --- a/defense_sim_v2/frontend/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020-PRESENT Anthony Fu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/defense_sim_v2/frontend/src/types/simulation.ts b/defense_sim_v2/frontend/src/types/simulation.ts deleted file mode 100644 index fd55233..0000000 --- a/defense_sim_v2/frontend/src/types/simulation.ts +++ /dev/null @@ -1,50 +0,0 @@ -export interface SimulationEntity { - id: string - type: string - active: boolean - position_ned_m: number[] - velocity_ned_m_s: number[] - acceleration_ned_m_s2: number[] - orientation_quaternion_wxyz?: number[] - angular_velocity_body_rad_s?: number[] - available?: boolean - activated_for?: string | null - position_error_ned_m?: number[] | null - velocity_error_ned_m_s?: number[] | null - trajectory_ned_m?: number[][] - intended_trajectory_ned_m?: number[][] - intention_kind?: string - standby_altitude_m?: number | null - flight_phase?: string -} - -export interface SimulationEvent { - type: string - time_s: number - threat_id?: string - defender_ids?: string[] - projectile_id?: string - target_id?: string - position_ned_m?: number[] - projected_city_crossing_ned_m?: number[] - miss_distance_m?: number - [key: string]: unknown -} - -export interface SimulationState { - schema_version: number - run_id: string - sequence: number - simulation_time_s: number - kind: 'simulation_state' - entities: SimulationEntity[] - events: SimulationEvent[] - environment: Record - devices?: Record - scenario?: Record - observations?: Record - radar_detection_points?: Record - radar_tracks?: Record - inferred_trajectories?: Record - statistics: Record -} diff --git a/defense_sim_v2/src/defense_sim/__init__.py b/defense_sim_v2/src/defense_sim/__init__.py deleted file mode 100644 index b116a70..0000000 --- a/defense_sim_v2/src/defense_sim/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Backend-authoritative defense simulation.""" - -__version__ = "0.1.0" diff --git a/defense_sim_v2/src/defense_sim/entities/drone.py b/defense_sim_v2/src/defense_sim/entities/drone.py deleted file mode 100644 index 0567c27..0000000 --- a/defense_sim_v2/src/defense_sim/entities/drone.py +++ /dev/null @@ -1,325 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass, field -import numpy as np -from ..physics.validation import finite_numeric_fields -from ..physics.atmosphere import isa -from ..physics.integrator import NUMBA_AVAILABLE, rk4_fast -if NUMBA_AVAILABLE: - from ..physics.integrator import drone_rk4_kernel -else: # pragma: no cover - numba optional - def drone_rk4_kernel(state, wind, held, drag_k, rho): - rel = state[3:] - wind - speed = float(np.linalg.norm(rel)) - return np.concatenate((state[3:], held + np.array([0.0, 0.0, 9.80665]) - - 0.5 * rho * drag_k * speed * rel)) - - -@dataclass -class DroneConfig: - mass_kg: float = 2.0 - max_acceleration_m_s2: float = 18.0 - max_speed_m_s: float = 25.0 - max_turn_rate_rad_s: float = 1.2 - max_climb_rate_m_s: float = 5.0 - max_descent_rate_m_s: float = 4.0 - acceleration_time_constant_s: float = 0.25 - drag_coefficient_area_m2: float = 0.08 - collision_radius_m: float = 0.5 - actuator_sigma_m_s2: float = 0.0 - # IR seeker model (used once the drone is tasked against a threat). - ir_range_m: float = 8_000.0 - ir_bearing_sigma_rad: float = .005 - ir_fov_deg: float = 120.0 - ir_position_sigma_m: float = 5.0 - ir_velocity_sigma_m_s: float = 1.0 - ir_update_rate_hz: float = 10.0 - ir_processing_latency_s: float = 0.01 - ir_lock_time_s: float = 1.0 - - @property - def ir_acquisition_time_s(self) -> float: - # Lock-on margin: seeker needs the configured lock time plus one - # processing/sample period before the estimate is usable. - return self.ir_lock_time_s + 1.0 / self.ir_update_rate_hz + self.ir_processing_latency_s - - @property - def ir_acquisition_range_m(self) -> float: - # Minimum distance at which the seeker can hold a lock long enough to - # produce a usable estimate. This is the standoff the interceptor - # geometry is built around. - return self.ir_acquisition_time_s * self.max_speed_m_s - - def __post_init__(self): - finite_numeric_fields(self) - if self.acceleration_time_constant_s <= 0 or self.max_turn_rate_rad_s < 0 or self.max_climb_rate_m_s <= 0 or self.max_descent_rate_m_s <= 0: - raise ValueError("invalid drone response/flight limits") - if self.drag_coefficient_area_m2 < 0 or self.collision_radius_m < 0 or self.actuator_sigma_m_s2 < 0: - raise ValueError("invalid drone drag/contact/noise parameters") - if self.mass_kg <= 0 or self.max_acceleration_m_s2 <= 0 or self.max_speed_m_s <= 0: - raise ValueError("invalid drone physical parameters") - if self.ir_range_m <= 0 or self.ir_position_sigma_m < 0 or self.ir_velocity_sigma_m_s < 0: - raise ValueError("invalid IR seeker parameters") - if self.ir_bearing_sigma_rad < 0 or not 0 < self.ir_fov_deg <= 360: - raise ValueError("invalid IR bearing noise/FOV") - if self.ir_update_rate_hz <= 0 or self.ir_processing_latency_s < 0 or self.ir_lock_time_s < 0: - raise ValueError("invalid IR seeker timing") - - -@dataclass -class Drone: - entity_id: str - entity_type: str - position_ned_m: np.ndarray - velocity_ned_m_s: np.ndarray = field(default_factory=lambda: np.zeros(3)) - config: DroneConfig = field(default_factory=DroneConfig) - acceleration_ned_m_s2: np.ndarray = field(default_factory=lambda: np.zeros(3)) - estimated_position_ned_m: np.ndarray | None = None - estimated_velocity_ned_m_s: np.ndarray | None = None - actuator_acceleration_ned_m_s2: np.ndarray = field(default_factory=lambda: np.zeros(3)) - requested_thrust_ned_m_s2: np.ndarray = field(default_factory=lambda: np.zeros(3)) - orientation_quaternion_wxyz: np.ndarray = field(default_factory=lambda: np.array([1., 0., 0., 0.])) - angular_velocity_body_rad_s: np.ndarray = field(default_factory=lambda: np.zeros(3)) - target_position_ned_m: np.ndarray | None = None - active: bool = True - available: bool = True - activated_for: str | None = None - # IR seeker state (threat-side): last estimate, lock age, acquisition flag. - ir_threat_estimate: np.ndarray | None = None # [position(3), velocity(3)] - ir_lock_age_s: float = 0.0 - ir_acquired: bool = False - ir_next_sample_s: float = 0.0 - ir_rng: np.random.Generator | None = None - flight_dynamics: object | None = None - flight_reference: dict | None = None - standby_altitude_m: float | None = None - ir_pending: list = field(default_factory=list) - ir_observation: dict | None = None - - def estimate_threat(self, target, time_s: float, rng: np.random.Generator, - event_sink: list | None = None, radar_prior=None) -> bool: - """Sample a rear-facing bearing-only IR camera, then deliver after delay. - - Visibility uses truth only in measurement generation. Range is never - measured by IR: the EKF retains the radar prior's range uncertainty. - Ideal attitude/gyro knowledge and no terrain occlusion are assumptions. - """ - if self.activated_for is None or self.ir_rng is None or target is None or not target.active: - return False - if time_s + 1e-9 >= self.ir_next_sample_s: - period = 1/self.config.ir_update_rate_hz - while self.ir_next_sample_s <= time_s+1e-9: - self.ir_next_sample_s += period - relative = target.position_ned_m-self.position_ned_m - distance = float(np.linalg.norm(relative)) - from scipy.spatial.transform import Rotation - rotation = Rotation.from_quat(self.orientation_quaternion_wxyz, scalar_first=True).as_matrix() - camera_axis = -rotation[:, 0] # rear-looking mount on body x axis - visible = (0 < distance <= self.config.ir_range_m and - float(relative @ camera_axis/distance) >= np.cos(np.deg2rad(self.config.ir_fov_deg/2))) - if not visible: - if self.ir_acquired and event_sink is not None: - event_sink.append({"type": "ir_track_lost", "time_s": time_s, "drone_id": self.entity_id}) - self.ir_lock_age_s = 0. - self.ir_acquired = False - self.ir_pending.clear() - self.ir_threat_estimate = None - self.ir_observation = None - else: - self.ir_lock_age_s += period - if self.ir_lock_age_s >= self.config.ir_lock_time_s: - # Elevation is mathematical +down to match Stone Soup's - # NED Cartesian model; physical elevation is its negative. - angles = np.array([np.arctan2(relative[2], np.linalg.norm(relative[:2])), - np.arctan2(relative[1], relative[0])]) - angles += self.ir_rng.normal(0, self.config.ir_bearing_sigma_rad, 2) - sensor_position = self.estimated_position_ned_m if self.estimated_position_ned_m is not None else self.position_ned_m - self.ir_pending.append({"sample_time_s": time_s, - "ready_time_s": time_s+self.config.ir_processing_latency_s, - "angles": angles, "sensor_position": sensor_position.copy()}) - due = [m for m in self.ir_pending if m["ready_time_s"] <= time_s+1e-9] - self.ir_pending = [m for m in self.ir_pending if m["ready_time_s"] > time_s+1e-9] - if not due or radar_prior is None: - return False - from ..sensors.tracking import refine_bearing - measurement = due[-1] - estimate = refine_bearing(radar_prior, measurement["sensor_position"], measurement["angles"], - measurement["sample_time_s"], self.config.ir_bearing_sigma_rad) - if estimate is None: - return False - acquired = not self.ir_acquired - self.ir_acquired = True - self.ir_threat_estimate = np.r_[estimate.position, estimate.velocity] - self.ir_observation = {"sample_time_s": estimate.timestamp_s, "receive_time_s": time_s, - "measurement_type": "bearing_only", "elevation_down_rad": float(measurement["angles"][0]), - "bearing_rad": float(measurement["angles"][1]), "covariance": estimate.covariance.tolist()} - if self.flight_reference is not None: - # Bearing-informed corrections retain radar range uncertainty. - # Keep along-path progress; smooth the lateral reference instead - # of overwriting the drone's actual position or velocity. - self.flight_reference["target_altitude_m"] = max(0., -estimate.position[2]) - direction = self.flight_reference["direction"][:2] - relative_estimate = estimate.position[:2]-measurement["sensor_position"][:2] - lateral = relative_estimate-direction*float(relative_estimate @ direction) - bound = self.config.max_speed_m_s/self.config.ir_update_rate_hz - lateral *= min(1., bound/max(float(np.linalg.norm(lateral)), 1e-9)) - self.flight_reference["anchor"][:2] += lateral - if event_sink is not None: - event_sink.append({"type": "ir_acquisition" if acquired else "ir_track_update", - "time_s": time_s, "drone_id": self.entity_id, "threat_id": self.activated_for, - **self.ir_observation}) - return True - - def control(self, dt: float, rng: np.random.Generator) -> None: - if self.target_position_ned_m is None: - desired_net = np.zeros(3) - else: - est = self.estimated_position_ned_m if self.estimated_position_ned_m is not None else self.position_ned_m - vel = self.estimated_velocity_ned_m_s if self.estimated_velocity_ned_m_s is not None else self.velocity_ned_m_s - desired_net = 1.4 * (self.target_position_ned_m - est) - 1.1 * vel - # Hover requires upward thrust to cancel NED gravity even at zero commanded net acceleration. - desired = desired_net + np.array([0.0, 0.0, -9.80665]) - # Preserve vertical support before allocating remaining thrust to - # planar motion. A distant horizontal reference must not silently - # remove hover thrust and make a grounded drone slide indefinitely. - limit = self.config.max_acceleration_m_s2 - desired[2] = np.clip(desired[2], -limit, limit) - horizontal = float(np.linalg.norm(desired[:2])) - budget = np.sqrt(max(0., limit*limit-desired[2]*desired[2])) - if horizontal > budget: - desired[:2] *= budget/max(horizontal, 1e-9) - self.requested_thrust_ned_m_s2 = desired + rng.normal(0, self.config.actuator_sigma_m_s2, 3) - n = np.linalg.norm(self.requested_thrust_ned_m_s2) - if n > self.config.max_acceleration_m_s2: - self.requested_thrust_ned_m_s2 *= self.config.max_acceleration_m_s2 / n - - def update_flight_reference(self, dt): - """A bounded gameplay ascent reference, never a position overwrite.""" - ref = self.flight_reference - if ref is None: - if self.standby_altitude_m is not None and self.target_position_ned_m is not None: - desired_down = -self.standby_altitude_m - self.target_position_ned_m[2] += float(np.clip(desired_down-self.target_position_ned_m[2], - -self.config.max_climb_rate_m_s*dt, self.config.max_descent_rate_m_s*dt)) - return - ref["elapsed_s"] += dt - previous = ref["previous_position"] - ref["travel_m"] += float(np.linalg.norm(self.position_ned_m[:2]-previous[:2])) - ref["previous_position"] = self.position_ned_m.copy() - initial_h = ref["initial_altitude_m"] - from ..guidance.ascent import altitude_reference - height = altitude_reference(ref["travel_m"], initial_h, ref["target_altitude_m"], - curve=ref.get("ascent_curve", "quintic"), length_m=ref.get("ascent_distance_m", 1000.), - k_per_m=ref["ascent_k_per_m"]) - # Limit the vertical reference rate; the actual vehicle has its own - # actuator/force dynamics and may fail to track this requested curve. - old_height = -self.target_position_ned_m[2] - height = old_height + float(np.clip(height-old_height, - -self.config.max_descent_rate_m_s*dt, self.config.max_climb_rate_m_s*dt)) - target = ref["anchor"].copy() - target[:2] += ref["direction"][:2]*ref["speed_m_s"]*ref["elapsed_s"] - target[2] = -height - # Smooth radar replans and lateral joins at the configured speed. - delta = target[:2]-self.target_position_ned_m[:2] - delta *= min(1., self.config.max_speed_m_s*dt/max(float(np.linalg.norm(delta)), 1e-9)) - self.target_position_ned_m[:2] += delta - self.target_position_ned_m[2] = target[2] - - def intended_trajectory(self, horizon_s=60., interval_s=1.): - """Preview the delivered command reference, not predicted physical flight. - - Uses onboard estimates, rate limits and the selected altitude curve. - Estimated horizontal travel advances the curve; actual flight may lag. - No controller, actuator, wind or collision prediction is implied. - """ - if not self.active or self.target_position_ned_m is None: - return [] - from ..guidance.ascent import altitude_reference - origin = (self.estimated_position_ned_m if self.estimated_position_ned_m is not None - else self.position_ned_m).copy() - point = origin.copy() - rows = [point.tolist()] - ref = self.flight_reference - travel = ref["travel_m"] if ref else 0. - for elapsed in np.arange(interval_s, horizon_s+1e-9, interval_s): - target = self.target_position_ned_m.copy() - if ref is not None: - target[:2] = ref["anchor"][:2] + ref["direction"][:2]*ref["speed_m_s"]*(ref["elapsed_s"]+elapsed) - target[2] = -altitude_reference(travel, ref["initial_altitude_m"], ref["target_altitude_m"], - curve=ref.get("ascent_curve", "quintic"), length_m=ref.get("ascent_distance_m", 1000.), - k_per_m=ref["ascent_k_per_m"]) - elif self.standby_altitude_m is not None: - target[2] = -self.standby_altitude_m - delta = target[:2]-point[:2] - delta *= min(1., self.config.max_speed_m_s*interval_s/max(float(np.linalg.norm(delta)), 1e-9)) - travel += float(np.linalg.norm(delta)) - point[:2] += delta - point[2] += float(np.clip(target[2]-point[2], -self.config.max_climb_rate_m_s*interval_s, - self.config.max_descent_rate_m_s*interval_s)) - rows.append(point.tolist()) - return rows - - def step(self, dt: float, wind: np.ndarray, rng: np.random.Generator, - control_due: bool = True, control_dt: float | None = None) -> None: - if not self.active: - return - self.update_flight_reference(dt) - if self.flight_dynamics is not None: - if self.activated_for is None and self.target_position_ned_m is None and self.position_ned_m[2] >= 0: - return - self.flight_dynamics.step(self, dt, wind, control_due) - return - # A defender that has not been tasked simply holds station on the - # loiter ring: it still responds to its actuator time constant (so a - # gust or a fresh command produces a realistic ramp) but it does not - # run the full guidance/controller/RK4 pipeline. This keeps idle - # units cheap -- the engine should not pay flight-control cost for - # drones that are not fighting -- and matches the doctrine that only - # the tasked interceptors fly. - if self.activated_for is None and self.target_position_ned_m is None: - if self.position_ned_m[2] >= 0 and np.linalg.norm(self.velocity_ned_m_s) < 1e-9: - self.position_ned_m[2] = 0.0 - self.acceleration_ned_m_s2 = np.zeros(3) - return # supported by the ground, not an unpowered hover - if not hasattr(self, "_hold_position_ned_m"): - self._hold_position_ned_m = self.position_ned_m.copy() - self.target_position_ned_m = self._hold_position_ned_m - # Tasked flight: controller output sampled at its device cadence; the - # held actuator state and vehicle dynamics continue at physics Hz. - if control_due: - self.control(control_dt if control_dt is not None else dt, rng) - # Motor surrogate evolves at physics cadence, independently of the - # command sample rate. Exact first-order decay avoids Euler clipping. - old_actuator = self.actuator_acceleration_ned_m_s2.copy() - tau = self.config.acceleration_time_constant_s - decay = np.exp(-dt / tau) - self.actuator_acceleration_ned_m_s2 = self.requested_thrust_ned_m_s2 + (old_actuator-self.requested_thrust_ned_m_s2)*decay - wind = np.asarray(wind, dtype=np.float64) - rho = isa(-self.position_ned_m[2]).density_kg_m3 - drag_k = self.config.drag_coefficient_area_m2 / self.config.mass_kg - held = self.requested_thrust_ned_m_s2 + (old_actuator-self.requested_thrust_ned_m_s2)*tau*(1-decay)/dt - old_velocity = self.velocity_ned_m_s.copy() - y = rk4_fast(np.concatenate((self.position_ned_m, self.velocity_ned_m_s)), dt, - drone_rk4_kernel, wind, held, drag_k, rho) - self.velocity_ned_m_s = y[3:] - speed = float(np.linalg.norm(self.velocity_ned_m_s)) - if speed > self.config.max_speed_m_s: - self.velocity_ned_m_s *= self.config.max_speed_m_s / speed - self.velocity_ned_m_s[2] = float(np.clip(self.velocity_ned_m_s[2], -self.config.max_climb_rate_m_s, self.config.max_descent_rate_m_s)) - # The reduced model treats speed bounds as kinematic constraints. - # Integrate realized bounded velocity rather than unclipped endpoint - # velocity; RotorPy is the force/attitude model for higher fidelity. - self.position_ned_m += .5*dt*(old_velocity+self.velocity_ned_m_s) - self.acceleration_ned_m_s2 = (self.velocity_ned_m_s-old_velocity)/dt - if self.position_ned_m[2] > 0: - self.position_ned_m[2] = 0.0 - self.velocity_ned_m_s[2] = min(0.0, self.velocity_ned_m_s[2]) - horizontal_speed = np.linalg.norm(self.velocity_ned_m_s[:2]) - if horizontal_speed > 1e-6: - yaw = float(np.arctan2(self.velocity_ned_m_s[1], self.velocity_ned_m_s[0])) - current_yaw = float(2 * np.arctan2(self.orientation_quaternion_wxyz[3], self.orientation_quaternion_wxyz[0])) - error = (yaw - current_yaw + np.pi) % (2 * np.pi) - np.pi - yaw_step = float(np.clip(error, -self.config.max_turn_rate_rad_s * dt, self.config.max_turn_rate_rad_s * dt)) - new_yaw = current_yaw + yaw_step - self.angular_velocity_body_rad_s = np.array([0.0, 0.0, yaw_step / dt]) - self.orientation_quaternion_wxyz = np.array([np.cos(new_yaw/2), 0.0, 0.0, np.sin(new_yaw/2)]) diff --git a/defense_sim_v2/src/defense_sim/guidance/ascent.py b/defense_sim_v2/src/defense_sim/guidance/ascent.py deleted file mode 100644 index 4752d9e..0000000 --- a/defense_sim_v2/src/defense_sim/guidance/ascent.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Distance-based altitude references; these never prescribe actual motion.""" -import numpy as np - - -def altitude_reference(distance_m, initial_altitude_m, target_altitude_m, *, - curve="quintic", length_m=1000., k_per_m=.002): - values = (distance_m, initial_altitude_m, target_altitude_m, length_m, k_per_m) - if not all(np.isfinite(value) for value in values) or length_m <= 0 or k_per_m <= 0: - raise ValueError("ascent reference parameters must be finite with positive L and k") - x = max(0., distance_m) - u = float(np.clip(x/length_m, 0., 1.)) - if curve == "quintic": - fraction = u*u*u*(10+u*(-15+6*u)) - elif curve == "cubic": - fraction = u*u*(3-2*u) - elif curve == "exponential": - fraction = -np.expm1(-k_per_m*x) - else: - raise ValueError("ascent curve must be quintic, cubic or exponential") - return float(initial_altitude_m+(target_altitude_m-initial_altitude_m)*fraction) - - -def automatic_ascent_length(rise_m, reference_speed_m_s, max_climb_rate_m_s, curve="quintic"): - """Heuristic L with 20% peak climb-rate margin at constant reference speed. - - Quintic peak dh/dx is 1.875*rise/L; cubic peak is 1.5*rise/L. - This does not guarantee acceleration feasibility or physical tracking. - """ - peak = 1.5 if curve == "cubic" else 1.875 - return float(max(500., peak*abs(rise_m)*reference_speed_m_s/(.8*max_climb_rate_m_s))) diff --git a/defense_sim_v2/src/defense_sim/guidance/trajectory.py b/defense_sim_v2/src/defense_sim/guidance/trajectory.py deleted file mode 100644 index 5765875..0000000 --- a/defense_sim_v2/src/defense_sim/guidance/trajectory.py +++ /dev/null @@ -1,221 +0,0 @@ -"""Estimated constant-velocity forecasts and reduced-model reference rollouts. - -The live controller uses ``predict_track`` with measured states only. Legacy -point-mass rollout helpers remain available for numerical/reference checks; -they must not be fed hidden attacker parameters by the defense controller. -""" -from __future__ import annotations - -from dataclasses import dataclass -import numpy as np - -from ..entities.projectile import Projectile -from ..physics.integrator import NUMBA_AVAILABLE, rk4_fast -from .activation import CityCircle -from ..physics.events import ground_fraction, circle_entry_fraction - -if NUMBA_AVAILABLE: - from ..physics.integrator import projectile_rk4_kernel -else: # pragma: no cover - numba optional - from ..entities.projectile import _drag_scalar - from ..physics.atmosphere import isa - - def projectile_rk4_kernel(state, wind, drag_k, thrust): - rel = state[3:] - wind - return np.concatenate((state[3:], np.array([0.0, 0.0, 9.80665]) - + isa(-state[2]).density_kg_m3 * _drag_scalar(rel, drag_k) + thrust)) - -PREDICTION_DT_S = 0.25 -PREDICTION_HORIZON_S = 600.0 -MIN_LINE_SAMPLES = 6 - - -@dataclass -class TrajectoryPrediction: - """Best-fit threat trajectory and intercept geometry for one threat.""" - - track_time_s: float - track_position_ned_m: np.ndarray - track_velocity_ned_m_s: np.ndarray - line_origin_ned_m: np.ndarray - line_direction_ned: np.ndarray # unit vector - crossing_ned_m: np.ndarray | None # primary intercept aim (first feasible crossing) - crossing_time_s: float | None - impact_ned_m: np.ndarray | None # predicted ground contact, if before the crossing - impact_time_s: float | None - samples: np.ndarray # (n, 4) -> time_s, x, y, z - time_to_crossing_s: float | None - - def point_at(self, delta_s: float) -> np.ndarray: - """Point on the threat line delta_s seconds from the crossing aim.""" - if self.crossing_ned_m is None: - return self.line_origin_ned_m - return self.crossing_ned_m + self.track_velocity_ned_m_s * delta_s - - -def predict_track(position, velocity, city, time_s, ceiling_m=3000., horizon_s=600.): - """Declared constant-velocity estimate; no aircraft truth or true wind. - - Forecast uncertainty grows with time. This extrapolation is useful for - displaying estimated motion and is not a certified flight prediction. - """ - position, velocity = np.asarray(position, dtype=float), np.asarray(velocity, dtype=float) - end = position + horizon_s*velocity - ground = ground_fraction(position, end) - entry = circle_entry_fraction(position, end, city.center_ned_m, city.radius_m) - crossing = crossing_t = impact = impact_t = None - if ground is not None: - impact = position + ground*(end-position) - impact_t = time_s+ground*horizon_s - if entry is not None and (ground is None or entry < ground): - point = position+entry*(end-position) - if -ceiling_m <= point[2] < 0: - crossing, crossing_t = point, time_s+entry*horizon_s - speed = float(np.linalg.norm(velocity)) - if speed < 1e-6: - return None - duration = min(horizon_s, ground*horizon_s) if ground is not None else horizon_s - times = np.linspace(0, duration, 61) - samples = np.column_stack((times, position + times[:, None]*velocity)) - return TrajectoryPrediction(time_s, position.copy(), velocity.copy(), position.copy(), velocity/speed, - crossing, crossing_t, impact, impact_t, samples, - crossing_t-time_s if crossing_t is not None else None) - - -def roll_out_threat(projectile: Projectile, position_ned_m: np.ndarray, - velocity_ned_m_s: np.ndarray, wind_ned_m_s: np.ndarray, - dt: float = PREDICTION_DT_S, horizon_s: float = PREDICTION_HORIZON_S) -> np.ndarray: - """Integrate the observed state forward; returns (n, 4) [t, x, y, z] rows. - - The whole horizon is integrated step-at-a-time with the same RK4 kernel - the real projectile uses (single-step fast path; the batch variant cannot - hold fixed args across a rollout whose altitude/drag changes each step), - and the rollout truncates at the first ground contact, exactly like the - previous loop. - """ - wind = np.asarray(wind_ned_m_s, dtype=np.float64) - drag_k = projectile.config.drag_coefficient * projectile.config.area_m2 / projectile.config.mass_kg - thrust = projectile._thrust_cmd if projectile.guidance is not None and projectile.guidance_active else np.zeros(3) - count = max(1, int(horizon_s / dt)) - state = np.ascontiguousarray(np.concatenate((position_ned_m, velocity_ned_m_s)), dtype=np.float64) - rows = [np.concatenate(([0.0], position_ned_m))] - for i in range(count): - previous = state.copy() - state = rk4_fast(state, dt, projectile_rk4_kernel, wind, drag_k, thrust) - p = state[:3] - ground = ground_fraction(previous[:3], p) - if ground is not None: - p = previous[:3] + ground*(p-previous[:3]) - p[2] = 0.0 - rows.append(np.concatenate(([(i+ground)*dt], p))) - break - rows.append(np.concatenate(([(i+1)*dt], p))) - return np.asarray(rows, dtype=float) - - -def fit_line(samples: np.ndarray) -> tuple[np.ndarray, np.ndarray] | None: - """Least-squares line through the rollout samples. - - Model: x(t) = origin + direction * t with |direction| = 1, origin at t=0. - Linear in origin and (unnormalized) direction: solved with lstsq. - Returns (origin, unit_direction) or None if the fit is degenerate. - """ - if samples.shape[0] < MIN_LINE_SAMPLES: - return None - t = samples[:, 0] - x = samples[:, 1:] - t = t - t[0] - # center the times for conditioning - tc = t - float(t.mean()) - matrix = np.column_stack((np.ones_like(tc), tc[:, None])) - solution, residuals, rank, _ = np.linalg.lstsq(matrix, x, rcond=None) - origin = solution[0] - solution[1] * float(t.mean()) - direction = solution[1] - norm = float(np.linalg.norm(direction)) - if norm < 1e-9: - return None - return origin, direction / norm - - -def predict_trajectory(projectile: Projectile, position_ned_m: np.ndarray, - velocity_ned_m_s: np.ndarray, wind_ned_m_s: np.ndarray, - city: CityCircle, loiter_ceiling_m: float, - track_time_s: float, - dt: float = PREDICTION_DT_S, horizon_s: float = PREDICTION_HORIZON_S - ) -> TrajectoryPrediction | None: - """Full prediction: rollout + line fit + 3D protected-circle crossing.""" - samples = roll_out_threat(projectile, position_ned_m, velocity_ned_m_s, wind_ned_m_s, dt, horizon_s) - fit = fit_line(samples) - if fit is None: - return None - origin, direction = fit - - center = np.asarray(city.center_ned_m, dtype=float) - radius = city.radius_m - crossing: np.ndarray | None = None - crossing_t: float | None = None - impact: np.ndarray | None = None - impact_t: float | None = None - - previous = samples[0, 1:] - previous_t = 0.0 - for row in samples[1:]: - t, current = float(row[0]), row[1:] - entry = circle_entry_fraction(previous, current, center, radius) - ground = ground_fraction(previous, current) - if entry is not None and (ground is None or entry < ground): - point = previous + entry*(current-previous) - if -loiter_ceiling_m <= point[2] < 0: - crossing = point - crossing_t = track_time_s + previous_t + entry*(t-previous_t) - break - if ground is not None: - impact = previous + ground*(current-previous) - impact_t = track_time_s + previous_t + ground*(t-previous_t) - break - previous, previous_t = current, t - time_to_crossing = crossing_t-track_time_s if crossing_t is not None else None - - return TrajectoryPrediction( - track_time_s=track_time_s, - track_position_ned_m=np.asarray(position_ned_m, dtype=float), - track_velocity_ned_m_s=np.asarray(velocity_ned_m_s, dtype=float), - line_origin_ned_m=origin, - line_direction_ned=direction, - crossing_ned_m=crossing, - crossing_time_s=crossing_t, - impact_ned_m=impact, - impact_time_s=impact_t, - samples=samples, - time_to_crossing_s=time_to_crossing, - ) - - -def intercept_waypoints(prediction: TrajectoryPrediction, count: int, - standoff_m: float, order: list[str]) -> dict[str, np.ndarray]: - """Waypoint per drone: lead ahead of the aim, middle on it, trail behind. - - `order` lists drone IDs from nearest-to-farthest of the aim point; the - nearest (lead) flies to the point standoff_m *before* the crossing along - the threat line, the middle one walks the crossing point itself, and the - trail one covers standoff_m *after* it so the threat cannot slip through. - """ - if prediction.crossing_ned_m is None: - origin = prediction.line_origin_ned_m - return {drone_id: origin.copy() for drone_id in order} - direction = prediction.line_direction_ned - # orient direction so that positive offset = toward the crossing - # (the line was fit over the whole rollout; the crossing is usually the - # latest feasible sample, so the direction points toward it already when - # the origin is the track position). Guard against the reversed case. - vector_to_crossing = prediction.crossing_ned_m - prediction.line_origin_ned_m - if float(np.dot(vector_to_crossing, direction)) < 0.0: - direction = -direction - offsets = [] - n = len(order) - for index in range(n): - # nearest drone -> largest standoff before the aim, farthest -> closest - remaining = n - 1 - index - offset = -standoff_m * remaining if n > 1 else 0.0 - offsets.append(offset) - return {drone_id: prediction.crossing_ned_m + direction * offset for drone_id, offset in zip(order, offsets)} diff --git a/defense_sim_v2/src/defense_sim/sensors/devices.py b/defense_sim_v2/src/defense_sim/sensors/devices.py deleted file mode 100644 index a30084c..0000000 --- a/defense_sim_v2/src/defense_sim/sensors/devices.py +++ /dev/null @@ -1,165 +0,0 @@ -"""Device profiles and timing taken from this repository's AERIS-10 design. - -The mechanical/electronic scan cadence is derived from the STM32 firmware's -runRadarPulseSequence() constants. Measurement uncertainty and a 7.1 ms fixed -processing delay follow simulate_trajectory_precision.py and remain explicit -R&D assumptions, not bench-qualified radar performance. -""" -from __future__ import annotations - -from dataclasses import dataclass -import numpy as np -from ..physics.validation import finite_numeric_fields - - -@dataclass(frozen=True) -class AerisRadarConfig: - model: str = "aeris_10x" - station_count: int = 8 - ring_radius_km: float = 12.0 - range_sigma_m: float = 2.0 - azimuth_sigma_deg: float = 0.5 - elevation_sigma_deg: float = 0.5 - doppler_sigma_m_s: float = 1.0 - wired_processing_latency_s: float = 0.0071 - half_sector_deg: float = 3.6 - elevation_limit_deg: float = 45.0 - elevation_step_deg: float = 3.0 - elevation_beam_half_width_deg: float = 1.5 - - @property - def max_range_m(self) -> float: - return 20_000.0 if self.model == "aeris_10x" else 3_000.0 - - @property - def azimuth_step_period_s(self) -> float: - # Firmware constants: 16 chirps at each PRI, 175.4 us guard, - # three phase patterns x 15 elevation sweeps, four 1 ms motor steps. - pulse_train_s = 16 * (167e-6 + 175e-6) + 175.4e-6 - return 15 * (3 * pulse_train_s) + 4e-3 - - @property - def full_azimuth_revisit_s(self) -> float: - return 50 * self.azimuth_step_period_s - - @property - def full_scan_update_hz(self) -> float: - return 1.0 / self.full_azimuth_revisit_s - - def __post_init__(self): - finite_numeric_fields(self) - if any(value < 0 for value in (self.range_sigma_m, self.azimuth_sigma_deg, self.elevation_sigma_deg, self.doppler_sigma_m_s, self.wired_processing_latency_s)): - raise ValueError("radar noise and latency must be nonnegative") - if self.elevation_step_deg <= 0 or self.half_sector_deg <= 0 or self.elevation_beam_half_width_deg <= 0: - raise ValueError("radar beam geometry must be positive") - if self.model not in {"aeris_10n", "aeris_10x"}: - raise ValueError("radar model must be aeris_10n or aeris_10x") - if not 1 <= self.station_count <= 16 or self.ring_radius_km <= 0: - raise ValueError("radar station count/ring radius are outside supported bounds") - - -@dataclass(frozen=True) -class DroneLinkConfig: - update_rate_hz: float = 20.0 - one_way_latency_s: float = 0.050 - latency_jitter_sigma_s: float = 0.005 - command_compute_latency_s: float = 0.010 - packet_loss_probability: float = 0.0 - bitrate_bps: float = 250_000.0 - packet_overhead_bytes: int = 24 - telemetry_payload_bytes: int = 64 - command_payload_bytes: int = 48 - - def __post_init__(self): - finite_numeric_fields(self) - if self.update_rate_hz <= 0 or self.one_way_latency_s < 0 or self.latency_jitter_sigma_s < 0 or self.bitrate_bps <= 0: - raise ValueError("invalid drone datalink timing") - if self.command_compute_latency_s < 0 or min(self.packet_overhead_bytes, self.telemetry_payload_bytes, self.command_payload_bytes) < 0: - raise ValueError("invalid packet sizes/processing delay") - if not 0 <= self.packet_loss_probability <= 1: - raise ValueError("packet loss probability must be in [0, 1]") - - -class Aeris10Radar: - """One scanning AERIS-10 site with a quantized 50-position azimuth scan.""" - - def __init__(self, radar_id: str, position_ned_m: np.ndarray, inward_heading_rad: float, - config: AerisRadarConfig, rng: np.random.Generator, initial_slot: int = 0): - self.radar_id = radar_id - self.position_ned_m = np.asarray(position_ned_m, dtype=float) - self.inward_heading_rad = float(inward_heading_rad) - self.config = config - self.rng = rng - self.azimuth_slot = int(initial_slot) % 50 - self.next_sweep_time_s = 0.0 - self.last_detection_time_s: float | None = None - - def scan(self, target, time_s: float) -> dict | None: - measurements = self.scan_dwell([target], time_s) - return measurements[0] if measurements else None - - def is_dwell_due(self, time_s: float) -> bool: - return time_s + 1e-9 >= self.next_sweep_time_s - - def scan_dwell(self, targets, time_s: float) -> list[dict]: - """One dwell pass over every candidate target. - - The slot advances once per dwell and each active target is evaluated - with the same beam/time state; a first target that is out of range or - out of beam can no longer consume the opportunity for later ones (F03). - Detection remains deterministic within geometry/range constraints: no - cross-section/SNR/clutter model is claimed here (R&D assumption). - """ - if not self.is_dwell_due(time_s): - return [] - period = self.config.azimuth_step_period_s - missed = max(0, int(np.floor((time_s - self.next_sweep_time_s + 1e-9) / period))) - self.azimuth_slot = (self.azimuth_slot + missed) % 50 - self.next_sweep_time_s += (missed + 1) * period - slot_heading = self.inward_heading_rad + self.azimuth_slot * (2 * np.pi / 50) - self.azimuth_slot = (self.azimuth_slot + 1) % 50 - measurements = [] - for target in targets: - measurement = self._evaluate_at_dwell(target, time_s, slot_heading) - if measurement is not None: - measurement["target_id"] = target.entity_id - measurements.append(measurement) - return measurements - - def _evaluate_at_dwell(self, target, time_s: float, slot_heading: float) -> dict | None: - relative = target.position_ned_m - self.position_ned_m - distance = float(np.linalg.norm(relative)) - if distance <= 1e-6 or distance > self.config.max_range_m: - return None - north, east, down = relative - azimuth = float(np.arctan2(east, north)) - azimuth_error = (azimuth - slot_heading + np.pi) % (2 * np.pi) - np.pi - if abs(azimuth_error) > np.deg2rad(self.config.half_sector_deg): - return None - elevation = float(np.arctan2(-down, np.hypot(north, east))) - if abs(elevation) > np.deg2rad(self.config.elevation_limit_deg): - return None - nearest_elevation_center = round(np.rad2deg(elevation) / self.config.elevation_step_deg) * self.config.elevation_step_deg - if abs(np.rad2deg(elevation) - nearest_elevation_center) > self.config.elevation_beam_half_width_deg: - return None - range_measured = distance + self.rng.normal(0, self.config.range_sigma_m) - azimuth_measured = azimuth + self.rng.normal(0, np.deg2rad(self.config.azimuth_sigma_deg)) - elevation_measured = elevation + self.rng.normal(0, np.deg2rad(self.config.elevation_sigma_deg)) - direction = np.array([np.cos(elevation_measured) * np.cos(azimuth_measured), - np.cos(elevation_measured) * np.sin(azimuth_measured), - -np.sin(elevation_measured)]) - position = self.position_ned_m + max(0.0, range_measured) * direction - line_of_sight = direction - radial_speed = float(np.dot(target.velocity_ned_m_s, relative / distance) - + self.rng.normal(0, self.config.doppler_sigma_m_s)) - self.last_detection_time_s = time_s - return {"radar_id": self.radar_id, "measurement_time_s": time_s, - "arrival_time_s": time_s + self.config.wired_processing_latency_s, - "position_ned_m": position, "line_of_sight_ned": line_of_sight, - "radial_velocity_m_s": radial_speed, - "sensor_position_ned_m": self.position_ned_m.copy(), - "range_sigma_m": self.config.range_sigma_m, - "azimuth_sigma_rad": np.deg2rad(self.config.azimuth_sigma_deg), - "elevation_sigma_rad": np.deg2rad(self.config.elevation_sigma_deg), - "range_m": range_measured, "azimuth_rad": azimuth_measured, - "elevation_rad": elevation_measured} diff --git a/defense_sim_v2/src/defense_sim/simulation/engine.py b/defense_sim_v2/src/defense_sim/simulation/engine.py deleted file mode 100644 index 087347b..0000000 --- a/defense_sim_v2/src/defense_sim/simulation/engine.py +++ /dev/null @@ -1,782 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass, field -import uuid -from copy import deepcopy -import math -import numpy as np -from ..entities.drone import Drone -from ..entities.projectile import Projectile -from ..physics.environment import Environment -from ..sensors.tracking import RadarTracker -from ..sensors.models import Observation, Sensor, SensorConfig -from ..guidance.activation import CityCircle, select_defenders, reachable_within -from ..guidance.ascent import automatic_ascent_length -from ..guidance.trajectory import predict_track -from ..physics.atmosphere import isa -from ..physics.events import sphere_entry_fraction, ground_fraction, circle_entry_fraction -from ..sensors.devices import Aeris10Radar, AerisRadarConfig, DroneLinkConfig - - -@dataclass -class SimulationEngine: - dt: float = 0.01 - seed: int | None = None - environment: Environment = field(default_factory=Environment) - city_circle: CityCircle | None = None - sensor_config: SensorConfig = field(default_factory=SensorConfig) - radar_config: AerisRadarConfig = field(default_factory=AerisRadarConfig) - drone_link_config: DroneLinkConfig = field(default_factory=DroneLinkConfig) - drone_control_rate_hz: float = 50.0 - projectiles: list[Projectile] = field(default_factory=list) - drones: list[Drone] = field(default_factory=list) - time_s: float = 0.0 - run_id: str = field(default_factory=lambda: str(uuid.uuid4())) - events: list[dict] = field(default_factory=list) - trajectory: dict = field(default_factory=dict) - closest_approach_m: dict = field(default_factory=dict) - record_interval_s: float = 0.2 - - def __post_init__(self): - if not np.isfinite(self.dt) or self.dt <= 0: - raise ValueError("simulation dt must be positive") - if not np.isfinite(self.record_interval_s) or self.record_interval_s <= 0: - raise ValueError("trajectory record interval must be positive") - ids = [e.entity_id for e in [*self.projectiles, *self.drones]] - if len(set(ids)) != len(ids): - raise ValueError("entity ids must be unique") - for entity in [*self.projectiles, *self.drones]: - for name in ("position_ned_m", "velocity_ned_m_s"): - value = np.asarray(getattr(entity, name), dtype=float) - if value.shape != (3,) or not np.isfinite(value).all(): - raise ValueError(f"{name} must be a finite 3-vector") - setattr(entity, name, value.copy()) - self.rng = np.random.default_rng(self.seed) - if not np.isfinite(self.drone_control_rate_hz) or not 0 < self.drone_control_rate_hz <= 1/self.dt: - raise ValueError("drone control rate must be positive") - self.sensors = {d.entity_id: Sensor(self.sensor_config, np.random.default_rng(self.rng.integers(0, 2**63))) for d in self.drones} - self.latest_observations = {} - self.radar_tracks = {} - self.radar_tracker = RadarTracker() - self.track_predictions = {} - self.radar_arrivals = [] - self.latest_detections: dict[str, dict] = {} - self.radar_detection_points = {} - self.pending_drone_commands = [] - self.standby_launches = {} - self.pending_drone_telemetry = [] - self.wireless_channel_free_time_s = 0.0 - self.wireless_airtime_s = 0.0 - self.remote_drone_estimates = {} - self.remote_drone_velocities = {} - self.remote_drone_estimate_times = {} - self.remote_drone_receive_times = {} - self.remote_drone_link_latencies = {} - self.remote_drone_telemetry_age_s = {} - self.next_control_time_s = {d.entity_id: 0.0 for d in self.drones} - self.activated_threats: set[str] = set() - self._last_activation_check_s: dict[str, float] = {} - for e in [*self.projectiles, *self.drones]: - self.trajectory[e.entity_id] = [np.asarray(e.position_ned_m, dtype=float).copy()] - self.closest_approach_m = {p.entity_id: float("inf") for p in self.projectiles} - for p in self.projectiles: - p.estimated_position_ned_m = None - p.estimated_velocity_ned_m_s = None - # Per-projectile defense lifecycle bookkeeping (assignment state - # machine: proposed -> sent -> acknowledged -> active -> released). - self.protected_entries: set[str] = set() - self.projectile_outcomes: dict[str, str] = {} - self.defense_assignments: dict[str, dict] = {} # threat_id -> assignment record - self.pending_assignment_commands_by_drone: dict[str, list[dict]] = {} - self.threat_release_events: list[tuple[float, str]] = [] # (time_s, threat_id) - self.radars = [] - if self.city_circle is not None: - ring_m = self.radar_config.ring_radius_km * 1000.0 - for index in range(self.radar_config.station_count): - angle = 2 * np.pi * index / self.radar_config.station_count - position = self.city_circle.center_ned_m + np.array([ring_m * np.cos(angle), ring_m * np.sin(angle), 0.0]) - radar_rng = np.random.default_rng(self.rng.integers(0, 2**63)) - self.radars.append(Aeris10Radar(f"aeris10_{index+1:02d}", position, angle + np.pi, - self.radar_config, radar_rng, initial_slot=int(radar_rng.integers(0, 50)))) - - def step(self) -> "SimulationEngine": - """Advance one physics step. Never serializes; use ``step_and_snapshot`` - when a JSON-able state is needed.""" - if not hasattr(self, "record_interval_s"): - self.record_interval_s = self.dt - # Observation -> controller -> actuator/physics; each controller only sees estimates. - moving = [p for p in self.projectiles if p.active] + [d for d in self.drones if d.active and (d.position_ned_m[2] < 0 or d.target_position_ned_m is not None)] - if moving: - altitude = float(np.mean([-e.position_ned_m[2] for e in moving])) - speed = float(np.mean([np.linalg.norm(e.velocity_ned_m_s-self.environment.wind_ned_m_s) for e in moving])) - else: - altitude, speed = 0., 0. - self.environment.update(self.dt, altitude, speed) - for d in self.drones: - if not d.active: - continue - sensor = self.sensors[d.entity_id] - # Nav samples run at their own cadence (default 10 Hz): the truth - # history is cheap to keep every step, but observe() (and with it - # telemetry queuing and RNG draws) only fires when due. - if not sensor.is_update_due(self.time_s) and not sensor.pending: - continue - obs = sensor.observe(d, self.time_s) - if obs is not None: - self.latest_observations[d.entity_id] = obs - self._queue_drone_telemetry(d.entity_id, obs) - # Radar scan cadence: a radar advances its azimuth dwell at most once - # per physics step (its 0.258 s slot period is far longer than dt), and - # one dwell evaluates ALL active targets with the same beam/time state - # before the slot advances -- target list order must not decide which - # threats get a chance to be detected (F03). - self._scan_radars() - self._deliver_radar_tracks() - self._deliver_drone_telemetry() - self._service_standby_launches() - projectile_tracks = dict(self.radar_tracks) - self._service_assignments() - self._activate_defenders(projectile_tracks) - self._deliver_drone_commands() - wind = self.environment.air_velocity_ned_m_s - previous = {e.entity_id: e.position_ned_m.copy() for e in [*self.projectiles, *self.drones]} - previous_velocity = {e.entity_id: e.velocity_ned_m_s.copy() for e in [*self.projectiles, *self.drones]} - previously_active = {e.entity_id: e.active for e in [*self.projectiles, *self.drones]} - for p in self.projectiles: - if p.guidance is not None and not p.guidance_active and p.active: - p.guidance_active = True - self.events.append({"type": "terminal_guidance_active", "time_s": self.time_s, - "projectile_id": p.entity_id, - "strike_target_ned_m": p.guidance.target_ned_m.tolist(), - "note": "terminal glide steering engaged on the strike target"}) - p.step(self.dt, wind, self.time_s) - control_period = 1.0 / self.drone_control_rate_hz - record_every = max(1, int(round(self.record_interval_s / self.dt))) if hasattr(self, "record_interval_s") else 1 - step_count = int(round(self.time_s / self.dt)) - for d in self.drones: - control_due = self.time_s + 1e-9 >= self.next_control_time_s[d.entity_id] - if control_due: - while self.next_control_time_s[d.entity_id] <= self.time_s + 1e-9: - self.next_control_time_s[d.entity_id] += control_period - d.step(self.dt, wind, self.rng, control_due=control_due, control_dt=control_period) - self.time_s += self.dt - self._resolve_physical_events(previous, previous_velocity) - for drone in self.drones: - if drone.active and drone.activated_for is not None: - threat = next((p for p in self.projectiles if p.entity_id == drone.activated_for), None) - drone.estimate_threat(threat, self.time_s, self.rng, self.events, - radar_prior=self.radar_tracks.get(drone.activated_for)) - self._release_finished_assignments() - record_now = step_count % record_every == 0 - for e in [*self.projectiles, *self.drones]: - if record_now or (previously_active[e.entity_id] and not e.active): - self.trajectory[e.entity_id].append(e.position_ned_m.copy()) - del self.trajectory[e.entity_id][:-1800] - return self - - def step_and_snapshot(self) -> dict: - """Advance one physics step and return a serialized snapshot. - - ``step`` itself never serializes (that was the dominant per-step cost); - callers that need a JSON-able state use this wrapper or ``snapshot``. - """ - self.step() - return self.snapshot() - - def _scan_radars(self): - """One dwell per radar per step, evaluating all active targets together.""" - targets = [p for p in self.projectiles if p.active] - if not targets: - return - for radar in self.radars: - for measurement in radar.scan_dwell(targets, self.time_s): - target_id = measurement["target_id"] - self.radar_arrivals.append(measurement) - history = self.radar_detection_points.setdefault(target_id, []) - history.append(measurement["position_ned_m"].tolist()) - del history[:-600] - prev = self.latest_detections.get(target_id) - if prev is None or measurement["measurement_time_s"] > prev["measurement_time_s"]: - self.latest_detections[target_id] = measurement - - def _deliver_radar_tracks(self): - due = [m for m in self.radar_arrivals if m["arrival_time_s"] <= self.time_s + 1e-9] - self.radar_arrivals = [m for m in self.radar_arrivals if m["arrival_time_s"] > self.time_s + 1e-9] - targets = {p.entity_id: p for p in self.projectiles if p.active} - for measurement in sorted(due, key=lambda m: (m["measurement_time_s"], m["radar_id"])): - target = targets.get(measurement["target_id"]) - if target is None: - continue - # One delivered position detection is enough for standby launch; - # velocity evidence and reachability gate only the later assignment. - self._request_standby_launches(target.entity_id) - estimate = self.radar_tracker.update(measurement) - if estimate is None: - continue - # Truth comparison is diagnostic only and never enters the filter. - obs = Observation(target.entity_id, estimate.timestamp_s, estimate.position, - estimate.velocity, target.position_ned_m-estimate.position, - target.velocity_ned_m_s-estimate.velocity, estimate.covariance, - estimate.sample_count, estimate.velocity_observable, - error_reference="truth_at_receive_minus_sample_time_estimate") - if self.city_circle is not None and estimate.velocity_observable: - prediction = predict_track(estimate.position, estimate.velocity, self.city_circle, estimate.timestamp_s) - if prediction is not None: - self.track_predictions[target.entity_id] = prediction.samples - self.radar_tracks[target.entity_id] = obs - self.latest_observations[target.entity_id] = obs - target.estimated_position_ned_m = estimate.position.copy() - target.estimated_velocity_ned_m_s = estimate.velocity.copy() - self.events.append({"type": "radar_track_update", "time_s": self.time_s, - "measurement_time_s": estimate.timestamp_s, "target_id": target.entity_id, - "radar_ids": [measurement["radar_id"]], "position_ned_m": estimate.position.tolist(), - "velocity_ned_m_s": estimate.velocity.tolist(), "covariance": estimate.covariance.tolist(), - "sample_count": estimate.sample_count, "velocity_observable": estimate.velocity_observable, - "velocity_estimation_rule": "stonesoup_constant_velocity_position_filter"}) - - def _deliver_drone_commands(self): - pending = [] - for command in self.pending_drone_commands: - if command["delivery_time_s"] > self.time_s + 1e-9: - pending.append(command) - continue - drone = next((d for d in self.drones if d.entity_id == command["drone_id"]), None) - if drone is None: - continue - target = next((p for p in self.projectiles if p.entity_id == command["threat_id"]), None) - if command.get("kind") == "standby_takeoff": - if not drone.active or drone.activated_for is not None or target is None or not target.active: - continue - drone.standby_altitude_m = max(-drone.position_ned_m[2], command["altitude_m"]) - drone.target_position_ned_m = drone.position_ned_m.copy() - self.standby_launches[drone.entity_id]["status"] = "active" - self.events.append({"type": "standby_takeoff_started", "time_s": self.time_s, - "drone_id": drone.entity_id, "threat_id": target.entity_id, - "standby_altitude_m": drone.standby_altitude_m, - "end_to_end_command_delay_s": self.time_s-command["computed_time_s"]}) - continue - record = self.defense_assignments.get(command["threat_id"]) - if not drone.active or target is None or not target.active or record is None: - continue - if command["computed_time_s"] <= getattr(drone, "_last_command_computed_time_s", -float("inf")): - continue - drone._last_command_computed_time_s = command["computed_time_s"] - drone.activated_for = command["threat_id"] - drone.standby_altitude_m = None - if drone.flight_reference is None: - drone.target_position_ned_m = drone.position_ned_m.copy() - reference = command.get("flight_reference") - if reference is not None: - if drone.flight_reference is None: - drone.flight_reference = {**reference, - "initial_altitude_m": -drone.position_ned_m[2], "travel_m": 0., "elapsed_s": 0., - "previous_position": drone.position_ned_m.copy()} - else: - # Preserve ascent progress and elapsed phase during replans. - drone.flight_reference["direction"] = reference["direction"].copy() - drone.flight_reference["target_altitude_m"] = reference["target_altitude_m"] - else: - drone.target_position_ned_m = command["target_position_ned_m"].copy() - record["status"][drone.entity_id] = "active" - if all(value == "active" for value in record["status"].values()) and not record.get("activation_recorded"): - record["activation_recorded"] = True - self.events.append({"type": "defenders_activated", "time_s": self.time_s, - "threat_id": target.entity_id, "defender_ids": record["defender_ids"]}) - self.events.append({"type": "drone_command_received", "time_s": self.time_s, - "command_sent_time_s": command["sent_time_s"], "drone_id": drone.entity_id, - "threat_id": command["threat_id"], - "end_to_end_command_delay_s": self.time_s - command["computed_time_s"], - "wireless_queue_delay_s": command["queue_delay_s"], - "wireless_airtime_s": command["airtime_s"], - "wireless_one_way_latency_s": self.time_s - command["sent_time_s"]}) - self.pending_drone_commands = pending - - def _request_standby_launches(self, threat_id): - scenario = getattr(self, "scenario_config", {}) - if not scenario.get("early_takeoff_enabled", True): - return - for drone in self.drones: - if drone.entity_type != "defense_drone" or not drone.active or not drone.available or drone.activated_for is not None: - continue - if drone.entity_id in self.standby_launches: - record = self.standby_launches[drone.entity_id] - previous_threat_active = any(p.active and p.entity_id == record["threat_id"] for p in self.projectiles) - if drone.standby_altitude_m is not None or record["threat_id"] == threat_id or previous_threat_active: - continue - # An alert for a terminated threat must not permanently block - # a later incident if its command never reached this drone. - self.pending_drone_commands = [c for c in self.pending_drone_commands - if not (c["drone_id"] == drone.entity_id and c.get("kind") == "standby_takeoff")] - self.standby_launches[drone.entity_id] = {"threat_id": threat_id, - "altitude_m": scenario.get("standby_altitude_m", 150.), "attempts": 0, - "last_send": -float("inf"), "status": "proposed"} - self._send_standby_command(drone.entity_id) - - def _send_standby_command(self, drone_id): - record = self.standby_launches[drone_id] - record["attempts"] += 1 - record["last_send"] = self.time_s - computed = self.time_s+self.drone_link_config.command_compute_latency_s - _, sent = self._wireless_transmit(computed, self.drone_link_config.command_payload_bytes) - if self.rng.random() < self.drone_link_config.packet_loss_probability: - record["status"] = "dropped" - self.events.append({"type": "standby_command_dropped", "time_s": self.time_s, - "drone_id": drone_id, "threat_id": record["threat_id"]}) - return - latency = max(0., self.drone_link_config.one_way_latency_s+self.rng.normal( - 0., self.drone_link_config.latency_jitter_sigma_s)) - record["status"] = "sent" - self.pending_drone_commands.append({"kind": "standby_takeoff", "drone_id": drone_id, - "threat_id": record["threat_id"], "altitude_m": record["altitude_m"], - "computed_time_s": computed, "delivery_time_s": sent+latency}) - self.events.append({"type": "standby_takeoff_requested", "time_s": self.time_s, - "drone_id": drone_id, "threat_id": record["threat_id"], "altitude_m": record["altitude_m"]}) - - def _service_standby_launches(self): - active_threats = {p.entity_id for p in self.projectiles if p.active} - for did, record in self.standby_launches.items(): - drone = next(d for d in self.drones if d.entity_id == did) - if not drone.active or drone.activated_for is not None or record["threat_id"] not in active_threats: - if record["status"] != "active": - record["status"] = "cancelled" - continue - if record["status"] in {"active", "failed", "cancelled"}: - continue - if any(c["drone_id"] == did and c.get("kind") == "standby_takeoff" for c in self.pending_drone_commands): - continue - if self.time_s-record["last_send"] < 1.: - continue - if record["attempts"] >= 3: - record["status"] = "failed" - self.events.append({"type": "standby_takeoff_failed", "time_s": self.time_s, - "drone_id": did, "threat_id": record["threat_id"]}) - else: - self._send_standby_command(did) - - def _queue_drone_telemetry(self, drone_id, observation): - if self.rng.random() < self.drone_link_config.packet_loss_probability: - self.events.append({"type": "drone_telemetry_dropped", "time_s": self.time_s, - "drone_id": drone_id}) - return - computed_at = self.time_s - request_time = computed_at - tx_start, transmitted_at = self._wireless_transmit(request_time, self.drone_link_config.telemetry_payload_bytes) - latency = max(0.0, self.drone_link_config.one_way_latency_s - + self.rng.normal(0.0, self.drone_link_config.latency_jitter_sigma_s)) - self.pending_drone_telemetry.append({"drone_id": drone_id, - "measurement_time_s": observation.timestamp_s, "position_ned_m": observation.position_ned_m.copy(), - "velocity_ned_m_s": observation.velocity_ned_m_s.copy(), "sent_time_s": float(transmitted_at), - "delivery_time_s": float(transmitted_at + latency), - "queue_delay_s": max(0.0, tx_start - request_time), - "airtime_s": transmitted_at - tx_start, "wireless_latency_s": latency}) - - def _wireless_transmit(self, request_time_s: float, payload_bytes: int): - """Serialize packets through one shared R&D half-duplex radio channel.""" - period = 1.0 / self.drone_link_config.update_rate_hz - slot = np.ceil((request_time_s - 1e-9) / period) * period - start = max(float(slot), self.wireless_channel_free_time_s) - airtime = (payload_bytes + self.drone_link_config.packet_overhead_bytes) * 8.0 / self.drone_link_config.bitrate_bps - end = start + airtime - self.wireless_channel_free_time_s = end - self.wireless_airtime_s += airtime - return start, end - - def _deliver_drone_telemetry(self): - pending = [] - for packet in self.pending_drone_telemetry: - if packet["delivery_time_s"] > self.time_s + 1e-9: - pending.append(packet) - continue - if packet["measurement_time_s"] <= self.remote_drone_estimate_times.get(packet["drone_id"], -float("inf")): - continue - self.remote_drone_estimates[packet["drone_id"]] = packet["position_ned_m"] - self.remote_drone_velocities[packet["drone_id"]] = packet.get("velocity_ned_m_s", np.zeros(3)) - self.remote_drone_estimate_times[packet["drone_id"]] = packet["measurement_time_s"] - self.remote_drone_receive_times[packet["drone_id"]] = self.time_s - self.remote_drone_link_latencies[packet["drone_id"]] = packet["wireless_latency_s"] - self.remote_drone_telemetry_age_s[packet["drone_id"]] = self.time_s - packet["measurement_time_s"] - self.pending_drone_telemetry = pending - - def _send_assignment_command(self, threat_id, drone_id): - record = self.defense_assignments[threat_id] - record["attempts"][drone_id] += 1 - record["last_send"][drone_id] = self.time_s - computed = self.time_s+self.drone_link_config.command_compute_latency_s - start, sent = self._wireless_transmit(computed, self.drone_link_config.command_payload_bytes) - if self.rng.random() < self.drone_link_config.packet_loss_probability: - if record["status"][drone_id] != "active": - record["status"][drone_id] = "dropped" - self.events.append({"type": "drone_command_dropped", "time_s": self.time_s, - "drone_id": drone_id, "threat_id": threat_id}) - return - latency = max(0., self.drone_link_config.one_way_latency_s + self.rng.normal(0., self.drone_link_config.latency_jitter_sigma_s)) - if record["status"][drone_id] != "active": - record["status"][drone_id] = "sent" - self.pending_drone_commands.append({"drone_id": drone_id, "threat_id": threat_id, - "target_position_ned_m": record["waypoints"][drone_id].copy(), - "flight_reference": deepcopy(record.get("references", {}).get(drone_id)), - "sent_time_s": sent, "computed_time_s": computed, - "queue_delay_s": max(0., start-computed), "airtime_s": sent-start, - "delivery_time_s": sent+latency}) - - def _service_assignments(self): - active_threats = {p.entity_id for p in self.projectiles if p.active} - for threat_id, record in list(self.defense_assignments.items()): - if threat_id not in active_threats: - continue - failed = False - for did in record["defender_ids"]: - if record["status"][did] == "active": - continue - # A queued packet may have long modeled serialization latency; - # do not retransmit it while it is still awaiting delivery. - if any(c["drone_id"] == did and c["threat_id"] == threat_id for c in self.pending_drone_commands): - continue - if self.time_s-record["last_send"][did] < 1.: - continue - if record["attempts"][did] >= 3: - failed = True - break - self._send_assignment_command(threat_id, did) - if failed: - self._release_assignment(threat_id, "command_delivery_failed") - continue - track = self.radar_tracks.get(threat_id) - if track is not None and track.velocity_observable and self.time_s-track.timestamp_s <= self.radar_config.full_azimuth_revisit_s*1.1 and self.time_s-record["last_replan_s"] >= 1.: - velocity = track.velocity_ned_m_s.copy() - velocity[2] = 0. - norm = float(np.linalg.norm(velocity)) - if norm > 1e-6: - for did, ref in record.get("references", {}).items(): - ref["direction"] = velocity/norm - ref["target_altitude_m"] = max(0., -(track.position_ned_m[2]+track.velocity_ned_m_s[2]*(self.time_s-track.timestamp_s))) - if record["status"][did] == "active" and not any(c["drone_id"] == did for c in self.pending_drone_commands): - self._send_assignment_command(threat_id, did) - record["last_replan_s"] = self.time_s - - def _release_assignment(self, threat_id, reason): - record = self.defense_assignments.pop(threat_id) - self.pending_drone_commands = [c for c in self.pending_drone_commands if c["threat_id"] != threat_id] - for did in record["defender_ids"]: - drone = next(d for d in self.drones if d.entity_id == did) - drone.activated_for = None - drone.flight_reference = None - drone.standby_altitude_m = None - drone.available = drone.active - drone.target_position_ned_m = drone.position_ned_m.copy() if drone.active and drone.position_ned_m[2] < 0 else None - self.events.append({"type": "defenders_released", "time_s": self.time_s, - "threat_id": threat_id, "defender_ids": record["defender_ids"], "reason": reason}) - - def _release_finished_assignments(self): - still_active = {p.entity_id for p in self.projectiles if p.active} - for threat_id in list(self.defense_assignments): - if threat_id not in still_active: - self._release_assignment(threat_id, "threat_terminated") - - def _activate_defenders(self, tracks): - """Reserve exactly three nearest defenders after sufficient evidence. - - Uses timestamped estimates and a declared constant-velocity forecast. - Reachability is a necessary kinematic screen, not a flight guarantee. - Commands, including replans, take effect only after link delivery. - """ - if self.city_circle is None: - return - self._release_finished_assignments() - for p in self.projectiles: - if not p.active or p.entity_id in self.activated_threats: - continue - if self.time_s - self._last_activation_check_s.get(p.entity_id, -1e9) < 1.0: - continue - self._last_activation_check_s[p.entity_id] = self.time_s - track = tracks.get(p.entity_id) - if track is None or not track.velocity_observable: - continue - if self.time_s - track.timestamp_s > self.radar_config.full_azimuth_revisit_s * 1.1: - continue - track_time = self.time_s - track_velocity = track.velocity_ned_m_s.copy() - track_position = track.position_ned_m + track_velocity * (self.time_s-track.timestamp_s) - prediction = predict_track(track_position, track_velocity, self.city_circle, - self.time_s, ceiling_m=3000.) - if prediction is not None: - self.track_predictions[p.entity_id] = prediction.samples - if prediction is None or prediction.crossing_ned_m is None: - continue - aim = prediction.crossing_ned_m - max_age_s = 2.0 / self.sensor_config.update_rate_hz + self.drone_link_config.one_way_latency_s + 0.05 - remote_positions = {drone_id: position+self.remote_drone_velocities.get(drone_id, np.zeros(3))*(self.time_s-self.remote_drone_estimate_times[drone_id]) - for drone_id, position in self.remote_drone_estimates.items() - if self.time_s - self.remote_drone_estimate_times.get(drone_id, -1e9) <= max_age_s} - if len(remote_positions) < 3: - continue - chosen = select_defenders(self.drones, aim, count=3, position_estimates=remote_positions, - path_segment=(track_position, aim)) - if len(chosen) < 3: - continue - # Finite future path: current estimate through first protected entry. - delta = aim-track_position - length2 = float(delta @ delta) - waypoints = {} - references = {} - direction = track_velocity.copy() - direction[2] = 0. - direction /= max(float(np.linalg.norm(direction)), 1e-9) - for drone in chosen: - position = remote_positions[drone.entity_id] - fraction = float(np.clip((position-track_position) @ delta/max(length2, 1e-9), 0, 1)) - waypoint = track_position+fraction*delta - waypoints[drone.entity_id] = waypoint - scenario = getattr(self, "scenario_config", {}) - curve = scenario.get("ascent_curve", "quintic") - speed = min(drone.config.max_speed_m_s*.8, float(np.linalg.norm(track_velocity[:2]))*.5) - length = scenario.get("ascent_distance_m") - if length is None: - length = automatic_ascent_length(-waypoint[2]+position[2], speed, drone.config.max_climb_rate_m_s, curve) - references[drone.entity_id] = {"anchor": waypoint.copy(), "direction": direction.copy(), - "target_altitude_m": max(0., -waypoint[2]), "speed_m_s": speed, - "ascent_curve": curve, "ascent_distance_m": length, - "ascent_k_per_m": scenario.get("ascent_k_per_m", .002)} - # Feasibility gate (F05): each defender must be able to reach its - # waypoint before the threat is predicted to pass it, using only - # estimates + declared vehicle limits. Infeasible assignments are - # reported rather than silently committed; the outcome always comes - # from simulated motion, never from this test declaring success. - crossing_time = prediction.crossing_time_s - velocity2 = float(track_velocity @ track_velocity) - airtime = 3*(self.drone_link_config.command_payload_bytes+self.drone_link_config.packet_overhead_bytes)*8/self.drone_link_config.bitrate_bps - delay = (self.drone_link_config.command_compute_latency_s + self.drone_link_config.one_way_latency_s - + 1/self.drone_link_config.update_rate_hz + airtime - + max(0., self.wireless_channel_free_time_s-self.time_s)) - available_times = {d.entity_id: float((waypoints[d.entity_id]-track_position) @ track_velocity/max(velocity2, 1e-9))-delay - for d in chosen} - feasible = [d for d in chosen if reachable_within( - remote_positions[d.entity_id], waypoints[d.entity_id], available_times[d.entity_id], - d.config.max_speed_m_s, d.config.max_climb_rate_m_s, d.config.max_descent_rate_m_s)] - if len(feasible) < 3: - self.events.append({"type": "defense_assignment_infeasible", "time_s": self.time_s, - "threat_id": p.entity_id, "nearest_defender_ids": [d.entity_id for d in chosen], - "reason": "reachability_gate_failed", - "projected_city_crossing_ned_m": aim.tolist(), - "crossing_time_s": crossing_time, "available_time_by_drone_s": available_times}) - continue - for drone in chosen: - drone.available = False - # Reservation is not a delivered launch command. - # Targets become executable only after command delivery. - # Seed the IR seeker RNG so the tasked drone can acquire the - # threat once inside seeker range. - if drone.ir_rng is None: - drone.ir_rng = np.random.default_rng(self.rng.integers(0, 2**63)) - self.defense_assignments[p.entity_id] = {"defender_ids": [d.entity_id for d in chosen], - "waypoints": waypoints, "references": references, "last_replan_s": self.time_s, "status": {d.entity_id: "proposed" for d in chosen}, - "attempts": {d.entity_id: 0 for d in chosen}, "last_send": {d.entity_id: -1e9 for d in chosen}} - for drone in chosen: - self._send_assignment_command(p.entity_id, drone.entity_id) - self.activated_threats.add(p.entity_id) - self.events.append({"type": "defenders_assigned", "time_s": self.time_s, - "threat_id": p.entity_id, "defender_ids": [d.entity_id for d in chosen], - "projected_city_crossing_ned_m": aim.tolist(), - "projected_threat_line_ned_m": prediction.line_origin_ned_m.tolist(), - "projected_threat_direction_ned": prediction.line_direction_ned.tolist(), - "waypoints_ned_m": {did: wp.tolist() for did, wp in waypoints.items()}, - "ascent_references": {did: {k: ref[k] for k in ("ascent_curve", "ascent_distance_m", "ascent_k_per_m")} for did, ref in references.items()}, - "ground_track_time_s": track.timestamp_s, - "radar_to_control_latency_s": self.time_s - track.timestamp_s, - "command_compute_latency_s": self.drone_link_config.command_compute_latency_s, - "wireless_update_rate_hz": self.drone_link_config.update_rate_hz, - "wireless_one_way_latency_s": self.drone_link_config.one_way_latency_s, - "selection_rule": "three nearest available defenders by 3D distance to finite estimated future path, ties by entity id"}) - - def _resolve_physical_events(self, previous, previous_velocity): - """Apply earliest events globally; ground wins an exact contact tie. - - Collision participants are consumed. Collision-as-neutralization is - an explicit game assumption, without blast/debris modeling. - """ - candidates = [] - for p in self.projectiles: - if not p.active: - continue - ground = ground_fraction(previous[p.entity_id], p.position_ned_m) - limit = ground if ground is not None else 1.0 - if ground is not None: - candidates.append((ground, 0, p.entity_id, "", "ground_impact")) - if self.city_circle is not None and p.entity_id not in self.protected_entries: - entry = circle_entry_fraction(previous[p.entity_id], p.position_ned_m, - self.city_circle.center_ned_m, self.city_circle.radius_m) - if entry is not None and (ground is None or entry < ground): - candidates.append((entry, 2, p.entity_id, "", "protected_area_entry")) - for d in self.drones: - if not d.active: - continue - r0 = previous[d.entity_id] - previous[p.entity_id] - r1 = d.position_ned_m - p.position_ned_m - delta = r1 - r0 - denom = float(delta @ delta) - nearest = float(np.clip(-float(r0 @ delta) / denom, 0, limit)) if denom else 0.0 - distance = float(np.linalg.norm(r0 + nearest * delta)) - self.closest_approach_m[p.entity_id] = min(self.closest_approach_m[p.entity_id], distance) - contact = sphere_entry_fraction(r0, r1, - p.config.collision_radius_m + d.config.collision_radius_m) - if contact is not None and contact <= limit: - candidates.append((contact, 1, p.entity_id, d.entity_id, "contact")) - by_projectile = {p.entity_id: p for p in self.projectiles} - by_drone = {d.entity_id: d for d in self.drones} - endpoints = {e.entity_id: e.position_ned_m.copy() for e in [*self.projectiles, *self.drones]} - endvel = {e.entity_id: e.velocity_ned_m_s.copy() for e in [*self.projectiles, *self.drones]} - for fraction, _, pid, did, kind in sorted(candidates): - p = by_projectile[pid] - if not p.active: - continue - position = previous[pid] + fraction * (endpoints[pid] - previous[pid]) - event_time = self.time_s - self.dt + fraction * self.dt - if kind == "protected_area_entry": - self.protected_entries.add(pid) - self.events.append({"type": kind, "time_s": event_time, - "projectile_id": pid, "position_ned_m": position.tolist()}) - continue - if kind == "contact": - d = by_drone[did] - if not d.active: - continue - d.position_ned_m = previous[did] + fraction * (endpoints[did] - previous[did]) - d.velocity_ned_m_s = previous_velocity[did] + fraction * (endvel[did] - previous_velocity[did]) - d.active, d.available = False, False - d.target_position_ned_m = None - kind = "interception" if d.entity_type == "defense_drone" else "collision" - outcome = "intercepted" if kind == "interception" else "collision" - event = {"type": kind, "time_s": event_time, "projectile_id": pid, - "target_id": did, "position_ned_m": position.tolist(), - "miss_distance_m": float(np.linalg.norm(d.position_ned_m - position)), - "intercept_error_ned_m": (d.position_ned_m - position).tolist(), - "neutralization_assumption": "contact_consumes_both"} - else: - position[2] = 0.0 - inside = self.city_circle is not None and float(np.linalg.norm( - position[:2] - self.city_circle.center_ned_m[:2])) <= self.city_circle.radius_m - outcome = "protected_impact" if inside else "safe_ground_impact" - event = {"type": "ground_impact", "time_s": event_time, - "projectile_id": pid, "position_ned_m": position.tolist(), "outcome": outcome} - p.position_ned_m = position - p.velocity_ned_m_s = previous_velocity[pid] + fraction * (endvel[pid] - previous_velocity[pid]) - p.active = False - event["velocity_ned_m_s"] = p.velocity_ned_m_s.tolist() - self.projectile_outcomes[pid] = outcome - self.events.append(event) - - def snapshot(self) -> dict: - entities = [] - for e in [*self.projectiles, *self.drones]: - kind = "projectile" if isinstance(e, Projectile) else e.entity_type - row = {"id": e.entity_id, "type": kind, "active": e.active, - "position_ned_m": e.position_ned_m.tolist(), "velocity_ned_m_s": e.velocity_ned_m_s.tolist(), - "acceleration_ned_m_s2": e.acceleration_ned_m_s2.tolist()} - if isinstance(e, Drone): - row.update({"orientation_quaternion_wxyz": e.orientation_quaternion_wxyz.tolist(), - "angular_velocity_body_rad_s": e.angular_velocity_body_rad_s.tolist(), - "position_error_ned_m": (e.position_ned_m - e.estimated_position_ned_m).tolist() if e.estimated_position_ned_m is not None else None, - "velocity_error_ned_m_s": (e.velocity_ned_m_s - e.estimated_velocity_ned_m_s).tolist() if e.estimated_velocity_ned_m_s is not None else None, - "actuator_acceleration_ned_m_s2": e.actuator_acceleration_ned_m_s2.tolist()}) - row.update({"available": e.available, "activated_for": e.activated_for, - "standby_altitude_m": e.standby_altitude_m, - "flight_phase": ("inactive" if not e.active else "assigned" if e.activated_for is not None - else ("standby_climb" if -e.position_ned_m[2] < e.standby_altitude_m-2 else "standby_hold") - if e.standby_altitude_m is not None else "takeoff_pending" - if self.standby_launches.get(e.entity_id, {}).get("status") == "sent" else "idle"), - "intended_trajectory_ned_m": e.intended_trajectory(), - "intention_kind": "delivered_command_reference", - "flight_dynamics": e.flight_dynamics.model_name if e.flight_dynamics is not None else "reduced_kinematic_surrogate", - "ir_acquired": e.ir_acquired, "ir_observation": e.ir_observation}) - elif e.estimated_position_ned_m is not None: - row.update({"estimated_position_ned_m": e.estimated_position_ned_m.tolist(), - "estimated_velocity_ned_m_s": e.estimated_velocity_ned_m_s.tolist(), - "position_error_ned_m": (e.position_ned_m - e.estimated_position_ned_m).tolist(), - "velocity_error_ned_m_s": (e.velocity_ned_m_s - e.estimated_velocity_ned_m_s).tolist()}) - if isinstance(e, Projectile) and e.guidance is not None: - row.update({"strike_target_ned_m": e.guidance.target_ned_m.tolist(), - "guidance_active": e.guidance_active, - "terminal_guidance": {"max_thrust_m_s2": e.guidance.max_thrust_m_s2, - "command_rate_hz": e.guidance.command_rate_hz}}) - row["trajectory_ned_m"] = np.asarray(self.trajectory[e.entity_id][-1800:]).tolist() - entities.append(row) - if entities: - reference_altitude = -float(np.mean([e["position_ned_m"][2] for e in entities])) - else: - reference_altitude = 0.0 - air = isa(reference_altitude) - observations = {key: {"timestamp_s": value.timestamp_s, - "position_ned_m": value.position_ned_m.tolist(), - "velocity_ned_m_s": value.velocity_ned_m_s.tolist(), - "position_error_ned_m": value.position_error_ned_m.tolist(), - "velocity_error_ned_m_s": value.velocity_error_ned_m_s.tolist(), - "error_reference": value.error_reference, - **({"control_station_receive_time_s": self.remote_drone_receive_times[key], - "wireless_one_way_latency_s": self.remote_drone_link_latencies[key], - "remote_measurement_time_s": self.remote_drone_estimate_times[key], - "remote_position_ned_m": self.remote_drone_estimates[key].tolist(), - "data_age_at_control_station_s": self.time_s - self.remote_drone_estimate_times[key]} - if key in self.remote_drone_receive_times else {})} - for key, value in self.latest_observations.items()} - closest = min(self.closest_approach_m.values(), default=float("inf")) - closest = closest if math.isfinite(closest) else None - return {"schema_version": 1, "run_id": self.run_id, "sequence": int(round(self.time_s / self.dt)), - "simulation_time_s": self.time_s, "kind": "simulation_state", "entities": entities, - "events": list(self.events[-250:]), "environment": {"wind_ned_m_s": self.environment.wind_ned_m_s.tolist(), - "gust_ned_m_s": self.environment.gust_ned_m_s.tolist(), - "altitude_m": reference_altitude, "temperature_k": air.temperature_k, "pressure_pa": air.pressure_pa, - "density_kg_m3": air.density_kg_m3, "speed_of_sound_m_s": air.speed_of_sound_m_s, - "viscosity_pa_s": air.viscosity_pa_s, - "city_center_ned_m": self.city_circle.center_ned_m.tolist() if self.city_circle else [0.0, 0.0, 0.0], - "city_radius_m": self.city_circle.radius_m if self.city_circle else 0.0, - "protected_radius_m": self.city_circle.radius_m if self.city_circle else 0.0, - "radar_radius_m": self.radar_config.ring_radius_km * 1000.0, - "drone_radius_m": (getattr(self, "scenario_config", {}).get("drone_radius_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_perimeter_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_ring_km", 0.0)) * 1000.0, - "defense_perimeter_radius_m": (getattr(self, "scenario_config", {}).get("drone_radius_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_perimeter_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_ring_km", 0.0)) * 1000.0, - "defense_ring_radius_m": (getattr(self, "scenario_config", {}).get("drone_radius_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_perimeter_km", 0.0) - or getattr(self, "scenario_config", {}).get("defense_ring_km", 0.0)) * 1000.0}, - "devices": {"radars": [{"id": r.radar_id, "position_ned_m": r.position_ned_m.tolist(), - "azimuth_slot": r.azimuth_slot, "last_detection_time_s": r.last_detection_time_s} - for r in self.radars], - "radar_profile": {"model": self.radar_config.model, "max_range_m": self.radar_config.max_range_m, - "azimuth_step_period_s": self.radar_config.azimuth_step_period_s, - "full_azimuth_revisit_s": self.radar_config.full_azimuth_revisit_s, - "wired_processing_latency_s": self.radar_config.wired_processing_latency_s}, - "wireless_link_profile": {"update_rate_hz": self.drone_link_config.update_rate_hz, - "one_way_latency_s": self.drone_link_config.one_way_latency_s, - "latency_jitter_sigma_s": self.drone_link_config.latency_jitter_sigma_s, - "command_compute_latency_s": self.drone_link_config.command_compute_latency_s, - "bitrate_bps": self.drone_link_config.bitrate_bps, - "packet_loss_probability": self.drone_link_config.packet_loss_probability, - "channel_airtime_s": self.wireless_airtime_s}, - "drone_control_rate_hz": self.drone_control_rate_hz}, - "scenario": getattr(self, "scenario_config", {}), "observations": observations, - "radar_tracks": {key: {"timestamp_s": value.timestamp_s, - "position_ned_m": value.position_ned_m.tolist(), - "velocity_ned_m_s": value.velocity_ned_m_s.tolist(), - "covariance": value.covariance.tolist() if value.covariance is not None else None, - "sample_count": value.sample_count, "velocity_observable": value.velocity_observable, - "age_s": self.time_s - value.timestamp_s} - for key, value in self.radar_tracks.items()}, - "radar_detection_points": self.radar_detection_points, - "inferred_trajectories": {key: value[:, 1:].tolist() for key, value in self.track_predictions.items()}, - "latest_detections": {key: {"radar_id": value["radar_id"], - "measurement_time_s": value["measurement_time_s"], - "position_ned_m": value["position_ned_m"].tolist(), - "line_of_sight_ned": value["line_of_sight_ned"].tolist(), - "radial_velocity_m_s": value["radial_velocity_m_s"]} - for key, value in self.latest_detections.items()}, - "statistics": {"elapsed_time_s": self.time_s, - "projectile_outcomes": {p.entity_id: self.projectile_outcomes.get(p.entity_id, "unresolved") for p in self.projectiles}, - "neutralization_assumption": "contact_consumes_both", - "protected_area_entry_count": len(self.protected_entries), - "interception_count": sum(e["type"] == "interception" for e in self.events), - "closest_approach_m": closest}} - - def run(self, steps: int) -> list[dict]: - return [self.step_and_snapshot() for _ in range(steps)] diff --git a/defense_sim_v2/tests/test_audit_regressions.py b/defense_sim_v2/tests/test_audit_regressions.py deleted file mode 100644 index 0e183b3..0000000 --- a/defense_sim_v2/tests/test_audit_regressions.py +++ /dev/null @@ -1,271 +0,0 @@ -import json -import numpy as np -import pytest - -from defense_sim.entities.drone import Drone, DroneConfig -from defense_sim.entities.projectile import Projectile, ProjectileConfig -from defense_sim.physics.events import sphere_entry_fraction, circle_entry_fraction -from defense_sim.physics.reference import integrate_reference -from defense_sim.sensors.tracking import RadarTracker -from defense_sim.simulation.engine import SimulationEngine -from defense_sim.statistics.monte_carlo import run_many -from defense_sim.sensors.models import Observation, SensorConfig -from defense_sim.guidance.activation import CityCircle - - -def projectile(position, velocity, radius=0.1, name="p"): - return Projectile(name, np.array(position, dtype=float), np.array(velocity, dtype=float), - ProjectileConfig(area_m2=0, collision_radius_m=radius)) - - -def drone(position, name="d", kind="defense_drone"): - return Drone(name, kind, np.array(position, dtype=float), config=DroneConfig(collision_radius_m=0.1)) - - -def test_contact_root_and_shallow_circle_chord(): - assert sphere_entry_fraction([-1, 0, 0], [1, 0, 0], 0.2) == pytest.approx(0.4) - assert circle_entry_fraction([-2, .9, -1], [2, .9, -1], [0, 0, 0], 1) is not None - - -def test_ground_precedes_underground_collision(): - p = projectile([0, 0, -1], [0, 0, 20], radius=.01) - sim = SimulationEngine(dt=.1, drone_control_rate_hz=10, seed=1, projectiles=[p], drones=[drone([0, 0, 1])]) - sim.step() - assert [e["type"] for e in sim.events] == ["ground_impact"] - assert p.position_ned_m[2] == 0 - assert p.velocity_ned_m_s[2] == pytest.approx(sim.events[0]["velocity_ned_m_s"][2]) - - -@pytest.mark.parametrize("reverse", [False, True]) -def test_first_contact_is_order_independent_and_consumes_drone(reverse): - p = projectile([-1, 0, -10], [200, 0, 0]) - drones = [drone([.5, 0, -10], "later"), drone([0, 0, -10], "earlier")] - if reverse: - drones.reverse() - sim = SimulationEngine(dt=.01, seed=1, projectiles=[p], drones=drones) - sim.step() - event = sim.events[0] - assert event["type"] == "interception" and event["target_id"] == "earlier" - assert event["time_s"] == pytest.approx(.004, abs=1e-6) - assert p.position_ned_m[0] == pytest.approx(-.2, abs=1e-5) - assert not next(d for d in drones if d.entity_id == "earlier").active - assert sim.trajectory["p"][-1][0] == pytest.approx(p.position_ned_m[0]) - - -def test_idle_ground_support_under_wind(): - d = drone([1, 2, 0]) - sim = SimulationEngine(seed=1, drones=[d]) - sim.environment.wind_ned_m_s = np.array([20., 3., 0.]) - for _ in range(500): - sim.step() - assert np.array_equal(d.position_ned_m, [1, 2, 0]) - assert np.array_equal(d.velocity_ned_m_s, np.zeros(3)) - - -def test_scipy_reference_matches_vacuum_ground_time_and_rk4(): - p = projectile([0, 0, -10], [20, 0, 0]) - state = np.r_[p.position_ned_m, p.velocity_ned_m_s] - reference = integrate_reference(lambda y: p.derivative(y, np.zeros(3)), state, 2, ground_event=True) - ground_time = np.sqrt(20/9.80665) - assert reference.t_events[0][0] == pytest.approx(ground_time, abs=1e-9) - p.step(.1, np.zeros(3)) - assert np.allclose(np.r_[p.position_ned_m, p.velocity_ned_m_s], reference.sol(.1), atol=1e-9) - - -def measurement(t, radar="r"): - position = np.array([1000.+10*t, 0, -10.]) - return {"target_id": "p", "radar_id": radar, "measurement_time_s": t, - "position_ned_m": position, "range_m": np.linalg.norm(position), - "azimuth_rad": 0., "elevation_rad": np.arctan2(10., position[0]), - "range_sigma_m": 1., "azimuth_sigma_rad": .001, "elevation_sigma_rad": .001} - - -def test_tracking_timestamp_covariance_and_velocity_evidence(): - tracker = RadarTracker(acceleration_diffusion=.01) - first = tracker.update(measurement(0)) - assert not first.velocity_observable - for t in (1., 2., 3.): - result = tracker.update(measurement(t)) - assert result.velocity_observable - assert result.velocity[0] == pytest.approx(10., abs=.1) - assert np.linalg.eigvalsh(result.covariance).min() > 0 - assert tracker.update(measurement(3)) is None - assert tracker.update(measurement(1, "other")) is None - - -def test_mature_tracks_and_event_covariance_serialize_as_strict_json(): - sim = SimulationEngine(seed=1, projectiles=[projectile([1000, 0, -10], [10, 0, 0])]) - for t in (0., 1., 2., 3.): - sim.time_s = t - sim.radar_arrivals.append({**measurement(t), 'arrival_time_s': t}) - sim._deliver_radar_tracks() - assert sim.radar_tracks['p'].velocity_observable - json.dumps(sim.snapshot(), allow_nan=False) - - -def test_monte_carlo_outcomes_are_per_projectile_and_cutoffs_censored(): - def factory(seed): - return SimulationEngine(seed=seed, projectiles=[ - projectile([-1, 0, -10], [200, 0, 0], name="hit"), - projectile([100, 0, -100], [0, 0, 0], name="unfinished")], - drones=[drone([0, 0, -10])]) - result = run_many(factory, runs=2, steps=1) - groups = result.aggregate["interception_by_projectile"] - assert groups["hit"]["interception_probability"] == 1 - assert groups["unfinished"]["interception_probability"] is None - assert groups["unfinished"]["unresolved_count"] == 2 - json.dumps(result.aggregate, allow_nan=False) - - -def launch_fixture(loss=0): - from defense_sim.sensors.devices import DroneLinkConfig - p = projectile([1000, 0, -20], [-50, 0, 0]) - from defense_sim.entities.projectile import ProjectileGuidanceConfig - p.guidance = ProjectileGuidanceConfig(np.array([0., 0., 0.]), max_thrust_m_s2=20.) - p.guidance_active = True - drones = [drone([500, i*5, 0], f'd{i}') for i in range(4)] - sim = SimulationEngine(seed=3, projectiles=[p], drones=drones, - city_circle=CityCircle(np.zeros(3), 500), - sensor_config=SensorConfig(position_sigma_m=0, velocity_sigma_m_s=0), - drone_link_config=DroneLinkConfig(packet_loss_probability=loss)) - track = Observation('p', 0., p.position_ned_m.copy(), p.velocity_ned_m_s.copy(), - np.zeros(3), np.zeros(3), np.eye(6), 5, True) - sim.radars = [] # this fixture isolates explicitly injected tracking evidence - sim.radar_tracks['p'] = track - sim.remote_drone_estimates = {d.entity_id: d.position_ned_m.copy() for d in drones} - sim.remote_drone_estimate_times = {d.entity_id: 0. for d in drones} - return sim - - -def test_launch_requires_evidence_and_delivered_commands(): - sim = launch_fixture() - sim.radar_tracks['p'].velocity_observable = False - sim._activate_defenders(sim.radar_tracks) - assert all(d.available for d in sim.drones) - sim.radar_tracks['p'].velocity_observable = True - sim.time_s = 1. - sim.remote_drone_estimate_times = {d.entity_id: 1. for d in sim.drones} - sim._activate_defenders(sim.radar_tracks) - assert sum(not d.available for d in sim.drones) == 3 - assert all(d.activated_for is None and d.target_position_ned_m is None for d in sim.drones) - sim.time_s = max(c['delivery_time_s'] for c in sim.pending_drone_commands)+.01 - sim._deliver_drone_commands() - assert sum(d.activated_for == 'p' for d in sim.drones) == 3 - for _ in range(500): - sim.step() - assert any(d.position_ned_m[2] < -.01 for d in sim.drones) - assert all(d.position_ned_m[2] <= 0 for d in sim.drones) - - -def test_total_packet_loss_retries_and_releases_reservations(): - sim = launch_fixture(loss=1.) - sim._activate_defenders(sim.radar_tracks) - for t in (1., 2., 3.): - sim.time_s = t - sim._service_assignments() - assert not sim.defense_assignments - assert all(d.available and d.activated_for is None for d in sim.drones) - assert len([e for e in sim.events if e['type'] == 'drone_command_dropped']) == 9 - - -def test_ir_bearing_only_processing_delay_and_loss(): - d = drone([0, 0, -10]) - d.activated_for = 'p' - d.ir_rng = np.random.default_rng(1) - d.config.ir_lock_time_s = 0. - d.config.ir_processing_latency_s = .05 - p = projectile([-100, 0, -10], [0, 0, 0]) - prior = Observation('p', 0., p.position_ned_m.copy(), np.zeros(3), np.zeros(3), - np.zeros(3), np.eye(6)*100, 5, True) - events = [] - assert not d.estimate_threat(p, 0., d.ir_rng, events, prior) - assert d.estimate_threat(p, .05, d.ir_rng, events, prior) - assert d.ir_observation['measurement_type'] == 'bearing_only' - assert 'range_m' not in d.ir_observation - p.position_ned_m = np.array([100., 0., -10.]) # outside rear-facing FOV - assert not d.estimate_threat(p, .1, d.ir_rng, events, prior) - assert not d.ir_acquired and d.ir_threat_estimate is None - - -@pytest.mark.parametrize('dt', [.1, .05, .025]) -def test_ground_event_converges_to_scipy_reference(dt): - p = projectile([0, 0, -10], [0, 0, 0]) - sim = SimulationEngine(dt=dt, drone_control_rate_hz=min(50, 1/dt), seed=1, projectiles=[p]) - while p.active: - sim.step() - analytic = np.sqrt(20/9.80665) - assert abs(sim.events[-1]['time_s']-analytic) < dt*dt - - -def test_atmosphere_high_altitude_and_nonfinite_rejected(): - from defense_sim.physics.atmosphere import isa - assert 1e-5 < isa(80000).density_kg_m3 < 3e-5 - assert isa(60000).density_kg_m3 < isa(20000).density_kg_m3/100 - with pytest.raises(ValueError): - DroneConfig(max_speed_m_s=float('nan')) - with pytest.raises(ValueError): - isa(90000) - - -def test_radar_dwell_evaluates_all_targets_and_preserves_clock_phase(): - from defense_sim.sensors.devices import Aeris10Radar, AerisRadarConfig - config = AerisRadarConfig(range_sigma_m=0, azimuth_sigma_deg=0, elevation_sigma_deg=0, doppler_sigma_m_s=0) - visible = projectile([1000, 0, -10], [-10, 0, 0], name='visible') - outside = projectile([30000, 0, -10], [-10, 0, 0], name='outside') - for targets in ([outside, visible], [visible, outside]): - radar = Aeris10Radar('r', np.zeros(3), 0, config, np.random.default_rng(3)) - assert [m['target_id'] for m in radar.scan_dwell(targets, 0)] == ['visible'] - for t in np.arange(.01, 13.01, .01): - radar.scan_dwell([], float(t)) - assert radar.next_sweep_time_s == pytest.approx(51*config.azimuth_step_period_s) - - -def test_telemetry_out_of_order_cannot_overwrite_newer_sample(): - sim = SimulationEngine(seed=1) - sim.time_s = 2. - base = {'drone_id': 'd', 'delivery_time_s': 1., 'wireless_latency_s': .1} - sim.pending_drone_telemetry = [ - {**base, 'measurement_time_s': 1., 'position_ned_m': np.ones(3)}, - {**base, 'measurement_time_s': .5, 'position_ned_m': np.zeros(3)}] - sim._deliver_drone_telemetry() - assert np.array_equal(sim.remote_drone_estimates['d'], np.ones(3)) - assert sim.remote_drone_estimate_times['d'] == 1. - - -def test_guidance_does_not_overwrite_velocity_or_create_zero_thrust(): - from defense_sim.entities.projectile import ProjectileGuidanceConfig - p = projectile([1000, 0, -100], [-50, 0, 0]) - p.guidance = ProjectileGuidanceConfig(np.zeros(3), max_thrust_m_s2=5.) - p.guidance_active = True - initial = p.velocity_ned_m_s.copy() - p.update_guidance(0., np.zeros(3)) - assert np.array_equal(p.velocity_ned_m_s, initial) - assert np.linalg.norm(p._thrust_cmd) <= 5.+1e-12 - p.guidance.max_thrust_m_s2 = 0. - p.update_guidance(1., np.zeros(3)) - assert np.array_equal(p._thrust_cmd, np.zeros(3)) - - -def test_ground_wins_tie_and_other_drone_contact_is_not_defense_success(): - p = projectile([0, 0, 0], [0, 0, 0]) - sim = SimulationEngine(seed=1, projectiles=[p], drones=[drone([0, 0, 0])]) - sim.step() - assert sim.events[0]['type'] == 'ground_impact' - q = projectile([-1, 0, -10], [200, 0, 0]) - sim = SimulationEngine(seed=1, projectiles=[q], drones=[drone([0, 0, -10], kind='attack_drone')]) - sim.step() - assert sim.events[0]['type'] == 'collision' - assert sim.projectile_outcomes['p'] == 'collision' - - -@pytest.mark.parametrize('reverse', [False, True]) -def test_consumed_drone_cannot_contact_later_threat(reverse): - first = projectile([-.8, 0, -10], [200, 0, 0], name='first') - later = projectile([-1., 0, -10], [200, 0, 0], name='later') - threats = [later, first] - if reverse: - threats.reverse() - sim = SimulationEngine(seed=1, projectiles=threats, drones=[drone([0, 0, -10])]) - sim.step() - assert not first.active and later.active - assert [e['projectile_id'] for e in sim.events if e['type'] == 'interception'] == ['first'] diff --git a/defense_sim_v2/tests/test_standby_and_trails.py b/defense_sim_v2/tests/test_standby_and_trails.py deleted file mode 100644 index cacfe5c..0000000 --- a/defense_sim_v2/tests/test_standby_and_trails.py +++ /dev/null @@ -1,101 +0,0 @@ -import json -import numpy as np -import pytest - -from defense_sim.simulation.scenarios import basic_intercept -from test_audit_regressions import launch_fixture, measurement - - -def detect_once(sim): - sim.radar_tracks.clear() - sim.radar_arrivals.append({**measurement(sim.time_s), 'arrival_time_s': sim.time_s}) - sim._deliver_radar_tracks() - - -def deliver_standby(sim): - sim.time_s = max(c['delivery_time_s'] for c in sim.pending_drone_commands)+.01 - sim._deliver_drone_commands() - - -def test_first_delivered_detection_launches_before_velocity_or_assignment(): - sim = launch_fixture() - sim.scenario_config = {'standby_altitude_m': 42., 'early_takeoff_enabled': True} - detect_once(sim) - assert not sim.radar_tracks['p'].velocity_observable - assert len(sim.pending_drone_commands) == 4 - assert all(d.target_position_ned_m is None for d in sim.drones) - assert not sim.defense_assignments - deliver_standby(sim) - assert all(d.standby_altitude_m == 42. and d.available and d.activated_for is None for d in sim.drones) - for _ in range(300): - sim.step() - assert all(d.position_ned_m[2] < -1 for d in sim.drones) - snapshot = sim.snapshot() - row = next(r for r in snapshot['entities'] if r['id'] == 'd0') - assert row['flight_phase'] == 'standby_climb' - intention = np.array(row['intended_trajectory_ned_m']) - assert intention[-1, 2] == pytest.approx(-42.) - assert np.allclose(intention[:, :2], intention[0, :2]) - assert not np.array_equal(intention, row['trajectory_ned_m']) - json.dumps(snapshot, allow_nan=False) - - -def test_early_takeoff_can_be_disabled_and_altitude_is_validated(): - sim = launch_fixture() - sim.scenario_config = {'early_takeoff_enabled': False} - detect_once(sim) - assert not sim.pending_drone_commands - for altitude in (0, -1, float('nan'), 3001): - with pytest.raises(ValueError): - basic_intercept(standby_altitude_m=altitude) - assert basic_intercept(standby_altitude_m=250.).scenario_config['standby_altitude_m'] == 250. - - -def test_standby_packets_retry_and_total_loss_does_not_launch(): - sim = launch_fixture(loss=1.) - detect_once(sim) - for t in (1., 2., 3.): - sim.time_s = t - sim._service_standby_launches() - assert not sim.pending_drone_commands - assert all(d.target_position_ned_m is None for d in sim.drones) - assert all(r['status'] == 'failed' and r['attempts'] == 3 for r in sim.standby_launches.values()) - - -def test_late_standby_packet_cannot_override_assignment(): - sim = launch_fixture() - detect_once(sim) - d = sim.drones[0] - d.activated_for = 'p' - d.target_position_ned_m = np.array([123., 456., -80.]) - deliver_standby(sim) - assert d.standby_altitude_m is None - assert np.array_equal(d.target_position_ned_m, [123., 456., -80.]) - - -def test_traces_persist_longer_than_old_six_second_window_and_samples_persist(): - sim = launch_fixture() - sim.scenario_config = {'early_takeoff_enabled': False} - sim.radar_detection_points['p'] = [[1000., 0., -20.]] - for _ in range(1000): - sim.step() - snapshot = sim.snapshot() - path = next(e['trajectory_ned_m'] for e in snapshot['entities'] if e['id'] == 'p') - assert path[0] == [1000., 0., -20.] - assert len(path) >= 50 - assert snapshot['radar_detection_points']['p'] == [[1000., 0., -20.]] - - -def test_intention_preview_does_not_advance_controller_or_truth(): - sim = launch_fixture() - sim._activate_defenders(sim.radar_tracks) - deliver_standby(sim) # helper delivers all queued packets, including assignment - d = next(d for d in sim.drones if d.flight_reference is not None) - position, target = d.position_ned_m.copy(), d.target_position_ned_m.copy() - travel, elapsed = d.flight_reference['travel_m'], d.flight_reference['elapsed_s'] - path = np.array(d.intended_trajectory()) - assert len(path) == 61 and np.isfinite(path).all() - assert np.linalg.norm(path[-1, :2]-path[0, :2]) > 0 - assert np.array_equal(position, d.position_ned_m) - assert np.array_equal(target, d.target_position_ned_m) - assert (travel, elapsed) == (d.flight_reference['travel_m'], d.flight_reference['elapsed_s']) diff --git a/docs/artifacts/te0713-te0701-heartbeat-2026-03-21.md b/docs/artifacts/te0713-te0701-heartbeat-2026-03-21.md index 98e68f4..ce90dc5 100644 --- a/docs/artifacts/te0713-te0701-heartbeat-2026-03-21.md +++ b/docs/artifacts/te0713-te0701-heartbeat-2026-03-21.md @@ -5,7 +5,7 @@ - Date: 2026-03-21 - Target: Trenz `TE0713-03-82C46-A` on `TE0701-06` - Top module: `radar_system_top_te0713_dev` -- Constraint file: `9_Firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc` +- Constraint file: `firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc` - Bitstream: `docs/artifacts/te0713-te0701-heartbeat-2026-03-21.bit` Build result: diff --git a/docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.md b/docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.md index 363c36e..ecb9c7d 100644 --- a/docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.md +++ b/docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.md @@ -72,7 +72,7 @@ Previous builds failed setup timing due to source-synchronous clock skew: ## Source Files -- `9_Firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v` — wrapper top -- `9_Firmware/9_2_FPGA/usb_data_interface.v` — FT601 USB data interface -- `9_Firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc` — FMC LPC constraints -- `9_Firmware/9_2_FPGA/scripts/build_te0713_umft601x_dev.tcl` — build script +- `firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v` — wrapper top +- `firmware/9_2_FPGA/usb_data_interface.v` — FT601 USB data interface +- `firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc` — FMC LPC constraints +- `firmware/9_2_FPGA/scripts/build_te0713_umft601x_dev.tcl` — build script diff --git a/docs/artifacts/te0713-te0701-umft601x-dev-timing-2026-03-21.rpt b/docs/artifacts/te0713-te0701-umft601x-dev-timing-2026-03-21.rpt index f12a211..4694250 100644 --- a/docs/artifacts/te0713-te0701-umft601x-dev-timing-2026-03-21.rpt +++ b/docs/artifacts/te0713-te0701-umft601x-dev-timing-2026-03-21.rpt @@ -3,7 +3,7 @@ Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. Copyright 2022-2025 Advanc | Tool Version : Vivado v.2025.2 (lin64) Build 6299465 Fri Nov 14 12:34:56 MST 2025 | Date : Sat Mar 21 20:41:16 2026 | Host : jason-pc running 64-bit Ubuntu 24.04.4 LTS -| Command : report_timing_summary -report_unconstrained -max_paths 100 -file /home/jason-stone/PLFM_RADAR_work/PLFM_RADAR/9_Firmware/9_2_FPGA/vivado_te0713_umft601x_dev/reports/timing_summary.rpt +| Command : report_timing_summary -report_unconstrained -max_paths 100 -file /home/jason-stone/PLFM_RADAR_work/PLFM_RADAR/firmware/9_2_FPGA/vivado_te0713_umft601x_dev/reports/timing_summary.rpt | Design : radar_system_top_te0713_umft601x_dev | Device : 7a200t-fbg484 | Speed File : -2 PRODUCTION 1.23 2018-06-13 diff --git a/docs/reports.html b/docs/reports.html index 456a875..e1392d4 100644 --- a/docs/reports.html +++ b/docs/reports.html @@ -493,12 +493,12 @@ - Production-target XDC9_Firmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdcConstraint source of truth for the production FPGA targetTracked and validated after Build 16 cleanup port - FPGA programming flow9_Firmware/9_2_FPGA/scripts/program_fpga.tclPrograms the device and reports DONE / INIT_COMPLETE / probes presencePrimary operator-facing programming script - Debug probe insertion flow9_Firmware/9_2_FPGA/scripts/insert_ila_probes.tclUsed when generating or refreshing debug-capable imagesKeep matched with the selected debug bitstream - FPGA regression runner9_Firmware/9_2_FPGA/run_regression.shPre-arrival regression evidence for the tracked FPGA baseline23 / 23 passing on the current tracked branch (includes CFAR + MTI + E2E tests) - MCU regression harness9_Firmware/9_1_Microcontroller/tests/MakefilePre-arrival firmware regression evidence before flashing hardware20 / 20 passing on the current tracked branch - Bring-up logging macros9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.hDefines the main first-power-on log vocabulary used over USART3Observation-only instrumentation layer + Production-target XDCfirmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdcConstraint source of truth for the production FPGA targetTracked and validated after Build 16 cleanup port + FPGA programming flowfirmware/9_2_FPGA/scripts/program_fpga.tclPrograms the device and reports DONE / INIT_COMPLETE / probes presencePrimary operator-facing programming script + Debug probe insertion flowfirmware/9_2_FPGA/scripts/insert_ila_probes.tclUsed when generating or refreshing debug-capable imagesKeep matched with the selected debug bitstream + FPGA regression runnerfirmware/9_2_FPGA/run_regression.shPre-arrival regression evidence for the tracked FPGA baseline23 / 23 passing on the current tracked branch (includes CFAR + MTI + E2E tests) + MCU regression harnessfirmware/9_1_Microcontroller/tests/MakefilePre-arrival firmware regression evidence before flashing hardware20 / 20 passing on the current tracked branch + Bring-up logging macrosfirmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.hDefines the main first-power-on log vocabulary used over USART3Observation-only instrumentation layer Board-day worksheetdocs/board-day-worksheet.htmlRecord pass/fail, measurements, and blockers during first sessionsUse with this page and the bring-up plan Bring-up execution plandocs/bring-up.htmlOperator checklist, abort criteria, observability targets, and open risksPrimary readiness document diff --git a/dual_radar_tracking_results.png b/dual_radar_tracking_results.png deleted file mode 100644 index e1f8e37bdbad09a9bb382da0bdbd67638c391dc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199960 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 fC2IF^COpWQg7R6SDw|&O)-kz<9zd8$E8~ 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

Zq235tajA0Tx@u+gRen!^xevLX0u=Q-}8 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

tY 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 TX, then configure ADAR1000s"); @@ -648,7 +648,7 @@ void ADAR1000Manager::setADTR1107Mode(BeamDirection direction) { } DIAG("BF", " ADTR1107 RX mode complete"); } -} +} void ADAR1000Manager::setADTR1107Control(bool tx_mode) { DIAG("BF", "setADTR1107Control(%s): setting TR switch on all %u devices, settling %lu us", @@ -727,7 +727,7 @@ void ADAR1000Manager::setLNABias(bool enable) { for (uint8_t dev = 0; dev < devices_.size(); ++dev) { adarWrite(dev, REG_LNA_BIAS_ON, lna_bias, BROADCAST_OFF); } -} +} void ADAR1000Manager::delayUs(uint32_t microseconds) { // Simple implementation - for F7 @ 216MHz, each loop ~7 cycles ≈ 0.032us @@ -903,11 +903,11 @@ void ADAR1000Manager::adarSetTxVgaGain(uint8_t deviceIndex, uint8_t channel, uin adarWrite(deviceIndex, REG_LOAD_WORKING, LD_WRK_REGS_LDTX_OVERRIDE, broadcast); } -void ADAR1000Manager::adarSetTxBias(uint8_t deviceIndex, uint8_t broadcast) { - adarWrite(deviceIndex, REG_BIAS_CURRENT_TX, kTxBiasCurrent, broadcast); - adarWrite(deviceIndex, REG_BIAS_CURRENT_TX_DRV, kTxDriverBiasCurrent, broadcast); - adarWrite(deviceIndex, REG_LOAD_WORKING, 0x2, broadcast); -} +void ADAR1000Manager::adarSetTxBias(uint8_t deviceIndex, uint8_t broadcast) { + adarWrite(deviceIndex, REG_BIAS_CURRENT_TX, kTxBiasCurrent, broadcast); + adarWrite(deviceIndex, REG_BIAS_CURRENT_TX_DRV, kTxDriverBiasCurrent, broadcast); + adarWrite(deviceIndex, REG_LOAD_WORKING, 0x2, broadcast); +} uint8_t ADAR1000Manager::adarAdcRead(uint8_t deviceIndex, uint8_t broadcast) { adarWrite(deviceIndex, REG_ADC_CONTROL, ADAR1000_ADC_ST_CONV, broadcast); diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.H b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.H similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.H rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.H diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DAC5578.H b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DAC5578.H similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DAC5578.H rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DAC5578.H diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.cpp b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.cpp rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPSPlus.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPSPlus.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPSPlus.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPSPlus.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.cpp b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.cpp rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/USBHandler.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382a_manager.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/diag_log.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.cpp b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.cpp rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/gps_handler.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_app.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_trigger.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_types.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_types.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_types.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iio_types.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod_private.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod_private.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod_private.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/iiod_private.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/jesd204.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/jesd204.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/jesd204.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/jesd204.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_ain.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_ain.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_ain.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_ain.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_alloc.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_aout.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_aout.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_aout.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_aout.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_axi_io.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_axi_io.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_axi_io.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_axi_io.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_circular_buffer.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_clk.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc16.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc24.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_crc8.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_delay.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_delay.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_delay.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_delay.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_dma.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_eeprom.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_error.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_error.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_error.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_error.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_fifo.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_flash.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_flash.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_flash.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_flash.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_font_8x8.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_font_8x8.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_font_8x8.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_font_8x8.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_gpio.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i2c.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_i3c.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_init.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_init.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_init.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_init.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_irq.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_lf256fifo.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_list.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mdio.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_mutex.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pid.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_print_log.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_print_log.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_print_log.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_print_log.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_pwm.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_rtc.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_rtc.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_rtc.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_rtc.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_semaphore.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_sin_lut.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_sin_lut.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_sin_lut.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_sin_lut.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_spi.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_tdm.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_timer.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_trng.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_uart.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_units.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_units.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_units.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_units.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/no_os_util.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.H b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.H similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.H rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.H diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/platform_noos_stm32.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_delay.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_gpio_irq.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_hal.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_hal.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_hal.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_hal.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_spi.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_timer.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_uart.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_conf.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_conf.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_conf.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_conf.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_hal_msp.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.h b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.h rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32f7xx_it.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/sysmem.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/sysmem.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/sysmem.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/sysmem.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/system_stm32f7xx.c b/firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/system_stm32f7xx.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/system_stm32f7xx.c rename to firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/system_stm32f7xx.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx b/firmware/9_1_Microcontroller/9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx rename to firmware/9_1_Microcontroller/9_1_2_C_Cpp_Algorithms/STM32_ALGO.docx diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp b/firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp rename to firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h b/firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h rename to firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.c b/firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.c rename to firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.c diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h b/firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h rename to firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h diff --git a/9_Firmware/9_1_Microcontroller/tests/.gitignore b/firmware/9_1_Microcontroller/tests/.gitignore similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/.gitignore rename to firmware/9_1_Microcontroller/tests/.gitignore diff --git a/9_Firmware/9_1_Microcontroller/tests/Makefile b/firmware/9_1_Microcontroller/tests/Makefile similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/Makefile rename to firmware/9_1_Microcontroller/tests/Makefile diff --git a/9_Firmware/9_1_Microcontroller/tests/ad_driver_mock.c b/firmware/9_1_Microcontroller/tests/ad_driver_mock.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/ad_driver_mock.c rename to firmware/9_1_Microcontroller/tests/ad_driver_mock.c diff --git a/9_Firmware/9_1_Microcontroller/tests/ad_driver_mock.h b/firmware/9_1_Microcontroller/tests/ad_driver_mock.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/ad_driver_mock.h rename to firmware/9_1_Microcontroller/tests/ad_driver_mock.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/adf4382.h b/firmware/9_1_Microcontroller/tests/shims/adf4382.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/adf4382.h rename to firmware/9_1_Microcontroller/tests/shims/adf4382.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/adf4382a_manager.h b/firmware/9_1_Microcontroller/tests/shims/adf4382a_manager.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/adf4382a_manager.h rename to firmware/9_1_Microcontroller/tests/shims/adf4382a_manager.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/diag_log.h b/firmware/9_1_Microcontroller/tests/shims/diag_log.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/diag_log.h rename to firmware/9_1_Microcontroller/tests/shims/diag_log.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/main.h b/firmware/9_1_Microcontroller/tests/shims/main.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/main.h rename to firmware/9_1_Microcontroller/tests/shims/main.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/no_os_delay.h b/firmware/9_1_Microcontroller/tests/shims/no_os_delay.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/no_os_delay.h rename to firmware/9_1_Microcontroller/tests/shims/no_os_delay.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/no_os_spi.h b/firmware/9_1_Microcontroller/tests/shims/no_os_spi.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/no_os_spi.h rename to firmware/9_1_Microcontroller/tests/shims/no_os_spi.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/no_os_units.h b/firmware/9_1_Microcontroller/tests/shims/no_os_units.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/no_os_units.h rename to firmware/9_1_Microcontroller/tests/shims/no_os_units.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/no_os_util.h b/firmware/9_1_Microcontroller/tests/shims/no_os_util.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/no_os_util.h rename to firmware/9_1_Microcontroller/tests/shims/no_os_util.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/platform_noos_stm32.h b/firmware/9_1_Microcontroller/tests/shims/platform_noos_stm32.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/platform_noos_stm32.h rename to firmware/9_1_Microcontroller/tests/shims/platform_noos_stm32.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/stm32_spi.h b/firmware/9_1_Microcontroller/tests/shims/stm32_spi.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/stm32_spi.h rename to firmware/9_1_Microcontroller/tests/shims/stm32_spi.h diff --git a/9_Firmware/9_1_Microcontroller/tests/shims/stm32f7xx_hal.h b/firmware/9_1_Microcontroller/tests/shims/stm32f7xx_hal.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/shims/stm32f7xx_hal.h rename to firmware/9_1_Microcontroller/tests/shims/stm32f7xx_hal.h diff --git a/9_Firmware/9_1_Microcontroller/tests/stm32_hal_mock.c b/firmware/9_1_Microcontroller/tests/stm32_hal_mock.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/stm32_hal_mock.c rename to firmware/9_1_Microcontroller/tests/stm32_hal_mock.c diff --git a/9_Firmware/9_1_Microcontroller/tests/stm32_hal_mock.h b/firmware/9_1_Microcontroller/tests/stm32_hal_mock.h similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/stm32_hal_mock.h rename to firmware/9_1_Microcontroller/tests/stm32_hal_mock.h diff --git a/9_Firmware/9_1_Microcontroller/tests/test_agc_outer_loop.cpp b/firmware/9_1_Microcontroller/tests/test_agc_outer_loop.cpp similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_agc_outer_loop.cpp rename to firmware/9_1_Microcontroller/tests/test_agc_outer_loop.cpp diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug10_spi_cs_not_toggled.c b/firmware/9_1_Microcontroller/tests/test_bug10_spi_cs_not_toggled.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug10_spi_cs_not_toggled.c rename to firmware/9_1_Microcontroller/tests/test_bug10_spi_cs_not_toggled.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug11_platform_spi_transmit_only.c b/firmware/9_1_Microcontroller/tests/test_bug11_platform_spi_transmit_only.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug11_platform_spi_transmit_only.c rename to firmware/9_1_Microcontroller/tests/test_bug11_platform_spi_transmit_only.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug12_pa_cal_loop_inverted.c b/firmware/9_1_Microcontroller/tests/test_bug12_pa_cal_loop_inverted.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug12_pa_cal_loop_inverted.c rename to firmware/9_1_Microcontroller/tests/test_bug12_pa_cal_loop_inverted.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug13_dac2_adc_buffer_mismatch.c b/firmware/9_1_Microcontroller/tests/test_bug13_dac2_adc_buffer_mismatch.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug13_dac2_adc_buffer_mismatch.c rename to firmware/9_1_Microcontroller/tests/test_bug13_dac2_adc_buffer_mismatch.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug14_diag_section_args.c b/firmware/9_1_Microcontroller/tests/test_bug14_diag_section_args.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug14_diag_section_args.c rename to firmware/9_1_Microcontroller/tests/test_bug14_diag_section_args.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug15_htim3_dangling_extern.c b/firmware/9_1_Microcontroller/tests/test_bug15_htim3_dangling_extern.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug15_htim3_dangling_extern.c rename to firmware/9_1_Microcontroller/tests/test_bug15_htim3_dangling_extern.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug1_timed_sync_init_ordering.c b/firmware/9_1_Microcontroller/tests/test_bug1_timed_sync_init_ordering.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug1_timed_sync_init_ordering.c rename to firmware/9_1_Microcontroller/tests/test_bug1_timed_sync_init_ordering.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug2_ad9523_double_setup.c b/firmware/9_1_Microcontroller/tests/test_bug2_ad9523_double_setup.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug2_ad9523_double_setup.c rename to firmware/9_1_Microcontroller/tests/test_bug2_ad9523_double_setup.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug3_timed_sync_noop.c b/firmware/9_1_Microcontroller/tests/test_bug3_timed_sync_noop.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug3_timed_sync_noop.c rename to firmware/9_1_Microcontroller/tests/test_bug3_timed_sync_noop.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug4_phase_shift_before_check.c b/firmware/9_1_Microcontroller/tests/test_bug4_phase_shift_before_check.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug4_phase_shift_before_check.c rename to firmware/9_1_Microcontroller/tests/test_bug4_phase_shift_before_check.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug5_fine_phase_gpio_only.c b/firmware/9_1_Microcontroller/tests/test_bug5_fine_phase_gpio_only.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug5_fine_phase_gpio_only.c rename to firmware/9_1_Microcontroller/tests/test_bug5_fine_phase_gpio_only.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug6_timer_variable_collision.c b/firmware/9_1_Microcontroller/tests/test_bug6_timer_variable_collision.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug6_timer_variable_collision.c rename to firmware/9_1_Microcontroller/tests/test_bug6_timer_variable_collision.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug7_gpio_pin_conflict.c b/firmware/9_1_Microcontroller/tests/test_bug7_gpio_pin_conflict.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug7_gpio_pin_conflict.c rename to firmware/9_1_Microcontroller/tests/test_bug7_gpio_pin_conflict.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c b/firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c similarity index 96% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c rename to firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c index b66a8af..4b6f9a9 100644 --- a/9_Firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c +++ b/firmware/9_1_Microcontroller/tests/test_bug8_uart_commented_out.c @@ -39,7 +39,7 @@ int main(void) long size; char *src = read_file(SOURCE_FILE, &size); if (!src) { - src = read_file("/Users/ganeshpanth/PLFM_RADAR/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp", &size); + src = read_file("/Users/ganeshpanth/PLFM_RADAR/firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp", &size); } assert(src != NULL && "Could not open main.cpp"); printf(" Read %ld bytes from main.cpp\n", size); diff --git a/9_Firmware/9_1_Microcontroller/tests/test_bug9_platform_ops_null.c b/firmware/9_1_Microcontroller/tests/test_bug9_platform_ops_null.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_bug9_platform_ops_null.c rename to firmware/9_1_Microcontroller/tests/test_bug9_platform_ops_null.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_emergency_state_ordering.c b/firmware/9_1_Microcontroller/tests/test_gap3_emergency_state_ordering.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_emergency_state_ordering.c rename to firmware/9_1_Microcontroller/tests/test_gap3_emergency_state_ordering.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_emergency_stop_rails.c b/firmware/9_1_Microcontroller/tests/test_gap3_emergency_stop_rails.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_emergency_stop_rails.c rename to firmware/9_1_Microcontroller/tests/test_gap3_emergency_stop_rails.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_health_watchdog_cold_start.c b/firmware/9_1_Microcontroller/tests/test_gap3_health_watchdog_cold_start.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_health_watchdog_cold_start.c rename to firmware/9_1_Microcontroller/tests/test_gap3_health_watchdog_cold_start.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_idq_periodic_reread.c b/firmware/9_1_Microcontroller/tests/test_gap3_idq_periodic_reread.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_idq_periodic_reread.c rename to firmware/9_1_Microcontroller/tests/test_gap3_idq_periodic_reread.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_iwdg_config.c b/firmware/9_1_Microcontroller/tests/test_gap3_iwdg_config.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_iwdg_config.c rename to firmware/9_1_Microcontroller/tests/test_gap3_iwdg_config.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_overtemp_emergency_stop.c b/firmware/9_1_Microcontroller/tests/test_gap3_overtemp_emergency_stop.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_overtemp_emergency_stop.c rename to firmware/9_1_Microcontroller/tests/test_gap3_overtemp_emergency_stop.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_gap3_temperature_max.c b/firmware/9_1_Microcontroller/tests/test_gap3_temperature_max.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_gap3_temperature_max.c rename to firmware/9_1_Microcontroller/tests/test_gap3_temperature_max.c diff --git a/9_Firmware/9_1_Microcontroller/tests/test_um982_gps.c b/firmware/9_1_Microcontroller/tests/test_um982_gps.c similarity index 100% rename from 9_Firmware/9_1_Microcontroller/tests/test_um982_gps.c rename to firmware/9_1_Microcontroller/tests/test_um982_gps.c diff --git a/9_Firmware/9_2_FPGA/.gitignore b/firmware/9_2_FPGA/.gitignore similarity index 100% rename from 9_Firmware/9_2_FPGA/.gitignore rename to firmware/9_2_FPGA/.gitignore diff --git a/9_Firmware/9_2_FPGA/ad9484_interface_400m.v b/firmware/9_2_FPGA/ad9484_interface_400m.v similarity index 100% rename from 9_Firmware/9_2_FPGA/ad9484_interface_400m.v rename to firmware/9_2_FPGA/ad9484_interface_400m.v diff --git a/9_Firmware/9_2_FPGA/adc_clk_mmcm.v b/firmware/9_2_FPGA/adc_clk_mmcm.v similarity index 100% rename from 9_Firmware/9_2_FPGA/adc_clk_mmcm.v rename to firmware/9_2_FPGA/adc_clk_mmcm.v diff --git a/9_Firmware/9_2_FPGA/adc_clk_mmcm_integration.md b/firmware/9_2_FPGA/adc_clk_mmcm_integration.md similarity index 100% rename from 9_Firmware/9_2_FPGA/adc_clk_mmcm_integration.md rename to firmware/9_2_FPGA/adc_clk_mmcm_integration.md diff --git a/9_Firmware/9_2_FPGA/cdc_modules.v b/firmware/9_2_FPGA/cdc_modules.v similarity index 100% rename from 9_Firmware/9_2_FPGA/cdc_modules.v rename to firmware/9_2_FPGA/cdc_modules.v diff --git a/9_Firmware/9_2_FPGA/cfar_ca.v b/firmware/9_2_FPGA/cfar_ca.v similarity index 100% rename from 9_Firmware/9_2_FPGA/cfar_ca.v rename to firmware/9_2_FPGA/cfar_ca.v diff --git a/9_Firmware/9_2_FPGA/chirp_memory_loader_param.v b/firmware/9_2_FPGA/chirp_memory_loader_param.v similarity index 100% rename from 9_Firmware/9_2_FPGA/chirp_memory_loader_param.v rename to firmware/9_2_FPGA/chirp_memory_loader_param.v diff --git a/9_Firmware/9_2_FPGA/cic_decimator_4x_enhanced.v b/firmware/9_2_FPGA/cic_decimator_4x_enhanced.v similarity index 100% rename from 9_Firmware/9_2_FPGA/cic_decimator_4x_enhanced.v rename to firmware/9_2_FPGA/cic_decimator_4x_enhanced.v diff --git a/9_Firmware/9_2_FPGA/constraints/README.md b/firmware/9_2_FPGA/constraints/README.md similarity index 99% rename from 9_Firmware/9_2_FPGA/constraints/README.md rename to firmware/9_2_FPGA/constraints/README.md index 8eb8705..7505643 100644 --- a/9_Firmware/9_2_FPGA/constraints/README.md +++ b/firmware/9_2_FPGA/constraints/README.md @@ -140,7 +140,7 @@ Channel A is used (245 Synchronous FIFO mode). Channel B is unconnected. ### Quick Reference ```bash -# From the FPGA source directory (9_Firmware/9_2_FPGA): +# From the FPGA source directory (firmware/9_2_FPGA): # 50T production build (FT2232H, USB_MODE=1): vivado -mode batch -source scripts/50t/build_50t.tcl 2>&1 | tee build_50t/vivado.log diff --git a/9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc b/firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc rename to firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/debug_ila.xdc b/firmware/9_2_FPGA/constraints/debug_ila.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/debug_ila.xdc rename to firmware/9_2_FPGA/constraints/debug_ila.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/te0712_te0701_minimal.xdc b/firmware/9_2_FPGA/constraints/te0712_te0701_minimal.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/te0712_te0701_minimal.xdc rename to firmware/9_2_FPGA/constraints/te0712_te0701_minimal.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc b/firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc rename to firmware/9_2_FPGA/constraints/te0713_te0701_minimal.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc b/firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc rename to firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdc b/firmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdc rename to firmware/9_2_FPGA/constraints/xc7a200t_fbg484.xdc diff --git a/9_Firmware/9_2_FPGA/constraints/xc7a50t_ftg256.xdc b/firmware/9_2_FPGA/constraints/xc7a50t_ftg256.xdc similarity index 100% rename from 9_Firmware/9_2_FPGA/constraints/xc7a50t_ftg256.xdc rename to firmware/9_2_FPGA/constraints/xc7a50t_ftg256.xdc diff --git a/9_Firmware/9_2_FPGA/dac_interface_single.v b/firmware/9_2_FPGA/dac_interface_single.v similarity index 100% rename from 9_Firmware/9_2_FPGA/dac_interface_single.v rename to firmware/9_2_FPGA/dac_interface_single.v diff --git a/9_Firmware/9_2_FPGA/ddc_400m.v b/firmware/9_2_FPGA/ddc_400m.v similarity index 100% rename from 9_Firmware/9_2_FPGA/ddc_400m.v rename to firmware/9_2_FPGA/ddc_400m.v diff --git a/9_Firmware/9_2_FPGA/ddc_input_interface.v b/firmware/9_2_FPGA/ddc_input_interface.v similarity index 100% rename from 9_Firmware/9_2_FPGA/ddc_input_interface.v rename to firmware/9_2_FPGA/ddc_input_interface.v diff --git a/9_Firmware/9_2_FPGA/doppler_processor.v b/firmware/9_2_FPGA/doppler_processor.v similarity index 100% rename from 9_Firmware/9_2_FPGA/doppler_processor.v rename to firmware/9_2_FPGA/doppler_processor.v diff --git a/9_Firmware/9_2_FPGA/edge_detector.v b/firmware/9_2_FPGA/edge_detector.v similarity index 100% rename from 9_Firmware/9_2_FPGA/edge_detector.v rename to firmware/9_2_FPGA/edge_detector.v diff --git a/9_Firmware/9_2_FPGA/fft_engine.v b/firmware/9_2_FPGA/fft_engine.v similarity index 100% rename from 9_Firmware/9_2_FPGA/fft_engine.v rename to firmware/9_2_FPGA/fft_engine.v diff --git a/9_Firmware/9_2_FPGA/fft_twiddle_1024.mem b/firmware/9_2_FPGA/fft_twiddle_1024.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/fft_twiddle_1024.mem rename to firmware/9_2_FPGA/fft_twiddle_1024.mem diff --git a/9_Firmware/9_2_FPGA/fft_twiddle_16.mem b/firmware/9_2_FPGA/fft_twiddle_16.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/fft_twiddle_16.mem rename to firmware/9_2_FPGA/fft_twiddle_16.mem diff --git a/9_Firmware/9_2_FPGA/fir_lowpass.v b/firmware/9_2_FPGA/fir_lowpass.v similarity index 100% rename from 9_Firmware/9_2_FPGA/fir_lowpass.v rename to firmware/9_2_FPGA/fir_lowpass.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_adc.sby b/firmware/9_2_FPGA/formal/fv_cdc_adc.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_adc.sby rename to firmware/9_2_FPGA/formal/fv_cdc_adc.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_adc.v b/firmware/9_2_FPGA/formal/fv_cdc_adc.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_adc.v rename to firmware/9_2_FPGA/formal/fv_cdc_adc.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_handshake.sby b/firmware/9_2_FPGA/formal/fv_cdc_handshake.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_handshake.sby rename to firmware/9_2_FPGA/formal/fv_cdc_handshake.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_handshake.v b/firmware/9_2_FPGA/formal/fv_cdc_handshake.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_handshake.v rename to firmware/9_2_FPGA/formal/fv_cdc_handshake.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_handshake_cover.sby b/firmware/9_2_FPGA/formal/fv_cdc_handshake_cover.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_handshake_cover.sby rename to firmware/9_2_FPGA/formal/fv_cdc_handshake_cover.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_single_bit.sby b/firmware/9_2_FPGA/formal/fv_cdc_single_bit.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_single_bit.sby rename to firmware/9_2_FPGA/formal/fv_cdc_single_bit.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_cdc_single_bit.v b/firmware/9_2_FPGA/formal/fv_cdc_single_bit.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_cdc_single_bit.v rename to firmware/9_2_FPGA/formal/fv_cdc_single_bit.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_doppler_processor.sby b/firmware/9_2_FPGA/formal/fv_doppler_processor.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_doppler_processor.sby rename to firmware/9_2_FPGA/formal/fv_doppler_processor.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_doppler_processor.v b/firmware/9_2_FPGA/formal/fv_doppler_processor.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_doppler_processor.v rename to firmware/9_2_FPGA/formal/fv_doppler_processor.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_radar_mode_controller.sby b/firmware/9_2_FPGA/formal/fv_radar_mode_controller.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_radar_mode_controller.sby rename to firmware/9_2_FPGA/formal/fv_radar_mode_controller.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_radar_mode_controller.v b/firmware/9_2_FPGA/formal/fv_radar_mode_controller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_radar_mode_controller.v rename to firmware/9_2_FPGA/formal/fv_radar_mode_controller.v diff --git a/9_Firmware/9_2_FPGA/formal/fv_range_bin_decimator.sby b/firmware/9_2_FPGA/formal/fv_range_bin_decimator.sby similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_range_bin_decimator.sby rename to firmware/9_2_FPGA/formal/fv_range_bin_decimator.sby diff --git a/9_Firmware/9_2_FPGA/formal/fv_range_bin_decimator.v b/firmware/9_2_FPGA/formal/fv_range_bin_decimator.v similarity index 100% rename from 9_Firmware/9_2_FPGA/formal/fv_range_bin_decimator.v rename to firmware/9_2_FPGA/formal/fv_range_bin_decimator.v diff --git a/9_Firmware/9_2_FPGA/fpga_self_test.v b/firmware/9_2_FPGA/fpga_self_test.v similarity index 100% rename from 9_Firmware/9_2_FPGA/fpga_self_test.v rename to firmware/9_2_FPGA/fpga_self_test.v diff --git a/9_Firmware/9_2_FPGA/frequency_matched_filter.v b/firmware/9_2_FPGA/frequency_matched_filter.v similarity index 100% rename from 9_Firmware/9_2_FPGA/frequency_matched_filter.v rename to firmware/9_2_FPGA/frequency_matched_filter.v diff --git a/9_Firmware/9_2_FPGA/latency_buffer.v b/firmware/9_2_FPGA/latency_buffer.v similarity index 100% rename from 9_Firmware/9_2_FPGA/latency_buffer.v rename to firmware/9_2_FPGA/latency_buffer.v diff --git a/9_Firmware/9_2_FPGA/long_chirp_lut.mem b/firmware/9_2_FPGA/long_chirp_lut.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_lut.mem rename to firmware/9_2_FPGA/long_chirp_lut.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg0_i.mem b/firmware/9_2_FPGA/long_chirp_seg0_i.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg0_i.mem rename to firmware/9_2_FPGA/long_chirp_seg0_i.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg0_q.mem b/firmware/9_2_FPGA/long_chirp_seg0_q.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg0_q.mem rename to firmware/9_2_FPGA/long_chirp_seg0_q.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg1_i.mem b/firmware/9_2_FPGA/long_chirp_seg1_i.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg1_i.mem rename to firmware/9_2_FPGA/long_chirp_seg1_i.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg1_q.mem b/firmware/9_2_FPGA/long_chirp_seg1_q.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg1_q.mem rename to firmware/9_2_FPGA/long_chirp_seg1_q.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg2_i.mem b/firmware/9_2_FPGA/long_chirp_seg2_i.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg2_i.mem rename to firmware/9_2_FPGA/long_chirp_seg2_i.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg2_q.mem b/firmware/9_2_FPGA/long_chirp_seg2_q.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg2_q.mem rename to firmware/9_2_FPGA/long_chirp_seg2_q.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg3_i.mem b/firmware/9_2_FPGA/long_chirp_seg3_i.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg3_i.mem rename to firmware/9_2_FPGA/long_chirp_seg3_i.mem diff --git a/9_Firmware/9_2_FPGA/long_chirp_seg3_q.mem b/firmware/9_2_FPGA/long_chirp_seg3_q.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/long_chirp_seg3_q.mem rename to firmware/9_2_FPGA/long_chirp_seg3_q.mem diff --git a/9_Firmware/9_2_FPGA/matched_filter_multi_segment.v b/firmware/9_2_FPGA/matched_filter_multi_segment.v similarity index 100% rename from 9_Firmware/9_2_FPGA/matched_filter_multi_segment.v rename to firmware/9_2_FPGA/matched_filter_multi_segment.v diff --git a/9_Firmware/9_2_FPGA/matched_filter_processing_chain.v b/firmware/9_2_FPGA/matched_filter_processing_chain.v similarity index 100% rename from 9_Firmware/9_2_FPGA/matched_filter_processing_chain.v rename to firmware/9_2_FPGA/matched_filter_processing_chain.v diff --git a/9_Firmware/9_2_FPGA/mti_canceller.v b/firmware/9_2_FPGA/mti_canceller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/mti_canceller.v rename to firmware/9_2_FPGA/mti_canceller.v diff --git a/9_Firmware/9_2_FPGA/nco_400m_enhanced.v b/firmware/9_2_FPGA/nco_400m_enhanced.v similarity index 100% rename from 9_Firmware/9_2_FPGA/nco_400m_enhanced.v rename to firmware/9_2_FPGA/nco_400m_enhanced.v diff --git a/9_Firmware/9_2_FPGA/plfm_chirp_controller.v b/firmware/9_2_FPGA/plfm_chirp_controller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/plfm_chirp_controller.v rename to firmware/9_2_FPGA/plfm_chirp_controller.v diff --git a/9_Firmware/9_2_FPGA/radar_mode_controller.v b/firmware/9_2_FPGA/radar_mode_controller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_mode_controller.v rename to firmware/9_2_FPGA/radar_mode_controller.v diff --git a/9_Firmware/9_2_FPGA/radar_receiver_final.v b/firmware/9_2_FPGA/radar_receiver_final.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_receiver_final.v rename to firmware/9_2_FPGA/radar_receiver_final.v diff --git a/9_Firmware/9_2_FPGA/radar_system_top.v b/firmware/9_2_FPGA/radar_system_top.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_system_top.v rename to firmware/9_2_FPGA/radar_system_top.v diff --git a/9_Firmware/9_2_FPGA/radar_system_top_50t.v b/firmware/9_2_FPGA/radar_system_top_50t.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_system_top_50t.v rename to firmware/9_2_FPGA/radar_system_top_50t.v diff --git a/9_Firmware/9_2_FPGA/radar_system_top_te0712_dev.v b/firmware/9_2_FPGA/radar_system_top_te0712_dev.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_system_top_te0712_dev.v rename to firmware/9_2_FPGA/radar_system_top_te0712_dev.v diff --git a/9_Firmware/9_2_FPGA/radar_system_top_te0713_dev.v b/firmware/9_2_FPGA/radar_system_top_te0713_dev.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_system_top_te0713_dev.v rename to firmware/9_2_FPGA/radar_system_top_te0713_dev.v diff --git a/9_Firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v b/firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v rename to firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v diff --git a/9_Firmware/9_2_FPGA/radar_transmitter.v b/firmware/9_2_FPGA/radar_transmitter.v similarity index 100% rename from 9_Firmware/9_2_FPGA/radar_transmitter.v rename to firmware/9_2_FPGA/radar_transmitter.v diff --git a/9_Firmware/9_2_FPGA/range_bin_decimator.v b/firmware/9_2_FPGA/range_bin_decimator.v similarity index 100% rename from 9_Firmware/9_2_FPGA/range_bin_decimator.v rename to firmware/9_2_FPGA/range_bin_decimator.v diff --git a/9_Firmware/9_2_FPGA/run_regression.sh b/firmware/9_2_FPGA/run_regression.sh similarity index 100% rename from 9_Firmware/9_2_FPGA/run_regression.sh rename to firmware/9_2_FPGA/run_regression.sh diff --git a/9_Firmware/9_2_FPGA/rx_gain_control.v b/firmware/9_2_FPGA/rx_gain_control.v similarity index 100% rename from 9_Firmware/9_2_FPGA/rx_gain_control.v rename to firmware/9_2_FPGA/rx_gain_control.v diff --git a/9_Firmware/9_2_FPGA/scripts/200t/build_200t.tcl b/firmware/9_2_FPGA/scripts/200t/build_200t.tcl similarity index 99% rename from 9_Firmware/9_2_FPGA/scripts/200t/build_200t.tcl rename to firmware/9_2_FPGA/scripts/200t/build_200t.tcl index f048cfa..aff20fc 100644 --- a/9_Firmware/9_2_FPGA/scripts/200t/build_200t.tcl +++ b/firmware/9_2_FPGA/scripts/200t/build_200t.tcl @@ -6,7 +6,7 @@ # Design: radar_system_top # # Usage: -# cd 9_Firmware/9_2_FPGA +# cd firmware/9_2_FPGA # vivado -mode batch -source scripts/200t/build_200t.tcl \ # -log build/build.log -journal build/build.jou ################################################################################ diff --git a/9_Firmware/9_2_FPGA/scripts/50t/build_50t.tcl b/firmware/9_2_FPGA/scripts/50t/build_50t.tcl similarity index 99% rename from 9_Firmware/9_2_FPGA/scripts/50t/build_50t.tcl rename to firmware/9_2_FPGA/scripts/50t/build_50t.tcl index 51a0e5e..db93adf 100644 --- a/9_Firmware/9_2_FPGA/scripts/50t/build_50t.tcl +++ b/firmware/9_2_FPGA/scripts/50t/build_50t.tcl @@ -3,7 +3,7 @@ # Builds the AERIS-10 design targeting the production 50T (FTG256) board # # Usage: -# cd 9_Firmware/9_2_FPGA +# cd firmware/9_2_FPGA # vivado -mode batch -source scripts/50t/build_50t.tcl 2>&1 | tee build_50t/vivado.log ################################################################################ diff --git a/9_Firmware/9_2_FPGA/scripts/te0712/build_te0712_dev.tcl b/firmware/9_2_FPGA/scripts/te0712/build_te0712_dev.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/te0712/build_te0712_dev.tcl rename to firmware/9_2_FPGA/scripts/te0712/build_te0712_dev.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/te0713/build_te0713_dev.tcl b/firmware/9_2_FPGA/scripts/te0713/build_te0713_dev.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/te0713/build_te0713_dev.tcl rename to firmware/9_2_FPGA/scripts/te0713/build_te0713_dev.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/te0713/build_te0713_umft601x_dev.tcl b/firmware/9_2_FPGA/scripts/te0713/build_te0713_umft601x_dev.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/te0713/build_te0713_umft601x_dev.tcl rename to firmware/9_2_FPGA/scripts/te0713/build_te0713_umft601x_dev.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/utils/ila_capture.tcl b/firmware/9_2_FPGA/scripts/utils/ila_capture.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/utils/ila_capture.tcl rename to firmware/9_2_FPGA/scripts/utils/ila_capture.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/utils/insert_ila_probes.tcl b/firmware/9_2_FPGA/scripts/utils/insert_ila_probes.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/utils/insert_ila_probes.tcl rename to firmware/9_2_FPGA/scripts/utils/insert_ila_probes.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/utils/program_fpga.tcl b/firmware/9_2_FPGA/scripts/utils/program_fpga.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/utils/program_fpga.tcl rename to firmware/9_2_FPGA/scripts/utils/program_fpga.tcl diff --git a/9_Firmware/9_2_FPGA/scripts/utils/run_cdc_and_netlist.tcl b/firmware/9_2_FPGA/scripts/utils/run_cdc_and_netlist.tcl similarity index 100% rename from 9_Firmware/9_2_FPGA/scripts/utils/run_cdc_and_netlist.tcl rename to firmware/9_2_FPGA/scripts/utils/run_cdc_and_netlist.tcl diff --git a/9_Firmware/9_2_FPGA/short_chirp_i.mem b/firmware/9_2_FPGA/short_chirp_i.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/short_chirp_i.mem rename to firmware/9_2_FPGA/short_chirp_i.mem diff --git a/9_Firmware/9_2_FPGA/short_chirp_q.mem b/firmware/9_2_FPGA/short_chirp_q.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/short_chirp_q.mem rename to firmware/9_2_FPGA/short_chirp_q.mem diff --git a/9_Firmware/9_2_FPGA/tb/ad9484_interface_400m_stub.v b/firmware/9_2_FPGA/tb/ad9484_interface_400m_stub.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/ad9484_interface_400m_stub.v rename to firmware/9_2_FPGA/tb/ad9484_interface_400m_stub.v diff --git a/9_Firmware/9_2_FPGA/tb/cic_dc_output.csv b/firmware/9_2_FPGA/tb/cic_dc_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cic_dc_output.csv rename to firmware/9_2_FPGA/tb/cic_dc_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/cic_impulse_output.csv b/firmware/9_2_FPGA/tb/cic_impulse_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cic_impulse_output.csv rename to firmware/9_2_FPGA/tb/cic_impulse_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/cic_sine_passband.csv b/firmware/9_2_FPGA/tb/cic_sine_passband.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cic_sine_passband.csv rename to firmware/9_2_FPGA/tb/cic_sine_passband.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/adc_dc.hex b/firmware/9_2_FPGA/tb/cosim/adc_dc.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/adc_dc.hex rename to firmware/9_2_FPGA/tb/cosim/adc_dc.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/adc_multi_target.hex b/firmware/9_2_FPGA/tb/cosim/adc_multi_target.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/adc_multi_target.hex rename to firmware/9_2_FPGA/tb/cosim/adc_multi_target.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/adc_noise_only.hex b/firmware/9_2_FPGA/tb/cosim/adc_noise_only.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/adc_noise_only.hex rename to firmware/9_2_FPGA/tb/cosim/adc_noise_only.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/adc_sine_1mhz.hex b/firmware/9_2_FPGA/tb/cosim/adc_sine_1mhz.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/adc_sine_1mhz.hex rename to firmware/9_2_FPGA/tb/cosim/adc_sine_1mhz.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/adc_single_target.hex b/firmware/9_2_FPGA/tb/cosim/adc_single_target.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/adc_single_target.hex rename to firmware/9_2_FPGA/tb/cosim/adc_single_target.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/bb_mf_test_i.hex b/firmware/9_2_FPGA/tb/cosim/bb_mf_test_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/bb_mf_test_i.hex rename to firmware/9_2_FPGA/tb/cosim/bb_mf_test_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/bb_mf_test_q.hex b/firmware/9_2_FPGA/tb/cosim/bb_mf_test_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/bb_mf_test_q.hex rename to firmware/9_2_FPGA/tb/cosim/bb_mf_test_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare.py b/firmware/9_2_FPGA/tb/cosim/compare.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare.py rename to firmware/9_2_FPGA/tb/cosim/compare.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_dc.csv b/firmware/9_2_FPGA/tb/cosim/compare_dc.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_dc.csv rename to firmware/9_2_FPGA/tb/cosim/compare_dc.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_doppler.py b/firmware/9_2_FPGA/tb/cosim/compare_doppler.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_doppler.py rename to firmware/9_2_FPGA/tb/cosim/compare_doppler.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_mf.py b/firmware/9_2_FPGA/tb/cosim/compare_mf.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_mf.py rename to firmware/9_2_FPGA/tb/cosim/compare_mf.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_mf_chirp.csv b/firmware/9_2_FPGA/tb/cosim/compare_mf_chirp.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_mf_chirp.csv rename to firmware/9_2_FPGA/tb/cosim/compare_mf_chirp.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_mf_dc.csv b/firmware/9_2_FPGA/tb/cosim/compare_mf_dc.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_mf_dc.csv rename to firmware/9_2_FPGA/tb/cosim/compare_mf_dc.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_mf_impulse.csv b/firmware/9_2_FPGA/tb/cosim/compare_mf_impulse.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_mf_impulse.csv rename to firmware/9_2_FPGA/tb/cosim/compare_mf_impulse.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_mf_tone5.csv b/firmware/9_2_FPGA/tb/cosim/compare_mf_tone5.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_mf_tone5.csv rename to firmware/9_2_FPGA/tb/cosim/compare_mf_tone5.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_multi_target.csv b/firmware/9_2_FPGA/tb/cosim/compare_multi_target.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_multi_target.csv rename to firmware/9_2_FPGA/tb/cosim/compare_multi_target.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_noise_only.csv b/firmware/9_2_FPGA/tb/cosim/compare_noise_only.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_noise_only.csv rename to firmware/9_2_FPGA/tb/cosim/compare_noise_only.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_sine_1mhz.csv b/firmware/9_2_FPGA/tb/cosim/compare_sine_1mhz.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_sine_1mhz.csv rename to firmware/9_2_FPGA/tb/cosim/compare_sine_1mhz.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/compare_single_target.csv b/firmware/9_2_FPGA/tb/cosim/compare_single_target.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/compare_single_target.csv rename to firmware/9_2_FPGA/tb/cosim/compare_single_target.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.csv b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.csv rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.hex b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_moving.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.csv b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.csv rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.hex b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_stationary.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.csv b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.csv rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.hex b/firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_golden_py_two_targets.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_input_moving.hex b/firmware/9_2_FPGA/tb/cosim/doppler_input_moving.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_input_moving.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_input_moving.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_input_stationary.hex b/firmware/9_2_FPGA/tb/cosim/doppler_input_stationary.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_input_stationary.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_input_stationary.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/doppler_input_two_targets.hex b/firmware/9_2_FPGA/tb/cosim/doppler_input_two_targets.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/doppler_input_two_targets.hex rename to firmware/9_2_FPGA/tb/cosim/doppler_input_two_targets.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/fpga_model.py b/firmware/9_2_FPGA/tb/cosim/fpga_model.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/fpga_model.py rename to firmware/9_2_FPGA/tb/cosim/fpga_model.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/gen_chirp_mem.py b/firmware/9_2_FPGA/tb/cosim/gen_chirp_mem.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/gen_chirp_mem.py rename to firmware/9_2_FPGA/tb/cosim/gen_chirp_mem.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py b/firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py rename to firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py index 61981a9..e759e6b 100644 --- a/9_Firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py +++ b/firmware/9_2_FPGA/tb/cosim/gen_doppler_golden.py @@ -11,7 +11,7 @@ Architecture: Sub-frame 1 (short PRI): chirps 16-31 -> 16-pt Hamming -> 16-pt FFT -> bins 16-31 Usage: - cd ~/PLFM_RADAR/9_Firmware/9_2_FPGA/tb/cosim + cd ~/PLFM_RADAR/firmware/9_2_FPGA/tb/cosim python3 gen_doppler_golden.py python3 gen_doppler_golden.py stationary # single scenario diff --git a/9_Firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py b/firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py rename to firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py index 2ac4de4..3f02fb9 100644 --- a/9_Firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py +++ b/firmware/9_2_FPGA/tb/cosim/gen_mf_cosim_golden.py @@ -12,7 +12,7 @@ SIMULATION-branch behavioral FFT in matched_filter_processing_chain.v. compare_mf.py then compares the two. Usage: - cd ~/PLFM_RADAR/9_Firmware/9_2_FPGA/tb/cosim + cd ~/PLFM_RADAR/firmware/9_2_FPGA/tb/cosim python3 gen_mf_cosim_golden.py Author: Phase 0.5 matched-filter co-simulation suite for PLFM_RADAR diff --git a/9_Firmware/9_2_FPGA/tb/cosim/gen_multiseg_golden.py b/firmware/9_2_FPGA/tb/cosim/gen_multiseg_golden.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/gen_multiseg_golden.py rename to firmware/9_2_FPGA/tb/cosim/gen_multiseg_golden.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_chirp.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_dc.csv b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_dc.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_dc.csv rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_dc.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_chirp.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_chirp.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_chirp.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_chirp.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_dc.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_impulse.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_impulse.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_impulse.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_impulse.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_tone5.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_tone5.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_tone5.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_i_tone5.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_impulse.csv b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_impulse.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_impulse.csv rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_impulse.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_chirp.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_chirp.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_chirp.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_chirp.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_dc.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_impulse.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_impulse.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_impulse.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_impulse.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_tone5.hex b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_tone5.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_tone5.hex rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_q_tone5.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv b/firmware/9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv rename to firmware/9_2_FPGA/tb/cosim/mf_golden_py_tone5.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_dc_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_dc_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_dc_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_dc_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_dc_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_dc_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_dc_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_dc_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_impulse_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_ref_tone5_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_dc_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_dc_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_dc_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_dc_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_dc_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_dc_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_dc_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_dc_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_impulse_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex b/firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex rename to firmware/9_2_FPGA/tb/cosim/mf_sig_tone5_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden.csv b/firmware/9_2_FPGA/tb/cosim/multiseg_golden.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden.csv rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg0_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg1_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg2_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_golden_seg3_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_input_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_input_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_input_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_input_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_input_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_input_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_input_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_input_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg0_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg1_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg2_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_ref_seg3_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden.csv b/firmware/9_2_FPGA/tb/cosim/multiseg_short_golden.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden.csv rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_golden.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_golden_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_input_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_input_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_input_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_input_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_input_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_input_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_input_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_input_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/multiseg_short_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/radar_scene.py b/firmware/9_2_FPGA/tb/cosim/radar_scene.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/radar_scene.py rename to firmware/9_2_FPGA/tb/cosim/radar_scene.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/golden_reference.py b/firmware/9_2_FPGA/tb/cosim/real_data/golden_reference.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/golden_reference.py rename to firmware/9_2_FPGA/tb/cosim/real_data/golden_reference.py diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md b/firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md similarity index 98% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md index 3eb73f6..64ed31f 100644 --- a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md +++ b/firmware/9_2_FPGA/tb/cosim/real_data/hex/STALE_NOTICE.md @@ -15,7 +15,7 @@ Regenerate whenever the Doppler processing pipeline changes: ## How to regenerate ```bash -cd 9_Firmware/9_2_FPGA +cd firmware/9_2_FPGA python3 tb/cosim/real_data/golden_reference.py # Then copy the Doppler-specific files: python3 -c " diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/adc_chirp0.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/adc_chirp0.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/adc_chirp0.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/adc_chirp0.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/chirp0_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/decimated_range_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/detection_mag.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/detection_mag.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/detection_mag.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/detection_mag.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/detections.txt b/firmware/9_2_FPGA/tb/cosim/real_data/hex/detections.txt similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/detections.txt rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/detections.txt diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_input_realdata.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_input_realdata.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_input_realdata.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_input_realdata.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_map_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/doppler_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_det.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_det.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_det.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_det.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_detections.txt b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_detections.txt similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_detections.txt rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_detections.txt diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_flags.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_flags.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_flags.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_flags.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_mag.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_cfar_thr.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detection_mag.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detection_mag.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detection_mag.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detection_mag.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detections.txt b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detections.txt similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detections.txt rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_detections.txt diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_packed.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_packed.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_packed.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_packed.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_doppler_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_doppler_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_mti_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_packed.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_packed.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_packed.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_packed.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_notched_ref_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_range_input.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_range_input.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_range_input.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/fullchain_range_input.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/post_ddc_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_i.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_i.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_i.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_i.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_q.npy b/firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_q.npy similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_q.npy rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_all_q.npy diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_i.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_i.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_q.hex b/firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_q.hex rename to firmware/9_2_FPGA/tb/cosim/real_data/hex/range_fft_chirp0_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/ref_chirp_i.hex b/firmware/9_2_FPGA/tb/cosim/ref_chirp_i.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/ref_chirp_i.hex rename to firmware/9_2_FPGA/tb/cosim/ref_chirp_i.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/ref_chirp_q.hex b/firmware/9_2_FPGA/tb/cosim/ref_chirp_q.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/ref_chirp_q.hex rename to firmware/9_2_FPGA/tb/cosim/ref_chirp_q.hex diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_dc.csv b/firmware/9_2_FPGA/tb/cosim/rtl_bb_dc.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_dc.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_bb_dc.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv b/firmware/9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_bb_multi_target.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv b/firmware/9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_bb_noise_only.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv b/firmware/9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_bb_sine_1mhz.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_single_target.csv b/firmware/9_2_FPGA/tb/cosim/rtl_bb_single_target.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_bb_single_target.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_bb_single_target.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_chirp.csv b/firmware/9_2_FPGA/tb/cosim/rtl_mf_chirp.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_chirp.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_mf_chirp.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_dc.csv b/firmware/9_2_FPGA/tb/cosim/rtl_mf_dc.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_dc.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_mf_dc.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_impulse.csv b/firmware/9_2_FPGA/tb/cosim/rtl_mf_impulse.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_impulse.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_mf_impulse.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_tone5.csv b/firmware/9_2_FPGA/tb/cosim/rtl_mf_tone5.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rtl_mf_tone5.csv rename to firmware/9_2_FPGA/tb/cosim/rtl_mf_tone5.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/rx_final_doppler_out.csv b/firmware/9_2_FPGA/tb/cosim/rx_final_doppler_out.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/rx_final_doppler_out.csv rename to firmware/9_2_FPGA/tb/cosim/rx_final_doppler_out.csv diff --git a/9_Firmware/9_2_FPGA/tb/cosim/scenario_info.txt b/firmware/9_2_FPGA/tb/cosim/scenario_info.txt similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/scenario_info.txt rename to firmware/9_2_FPGA/tb/cosim/scenario_info.txt diff --git a/9_Firmware/9_2_FPGA/tb/cosim/validate_mem_files.py b/firmware/9_2_FPGA/tb/cosim/validate_mem_files.py similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/cosim/validate_mem_files.py rename to firmware/9_2_FPGA/tb/cosim/validate_mem_files.py diff --git a/9_Firmware/9_2_FPGA/tb/ddc_120mhz_output.csv b/firmware/9_2_FPGA/tb/ddc_120mhz_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/ddc_120mhz_output.csv rename to firmware/9_2_FPGA/tb/ddc_120mhz_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/fir_dc_output.csv b/firmware/9_2_FPGA/tb/fir_dc_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/fir_dc_output.csv rename to firmware/9_2_FPGA/tb/fir_dc_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/fir_impulse_output.csv b/firmware/9_2_FPGA/tb/fir_impulse_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/fir_impulse_output.csv rename to firmware/9_2_FPGA/tb/fir_impulse_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/fir_sine_passband.csv b/firmware/9_2_FPGA/tb/fir_sine_passband.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/fir_sine_passband.csv rename to firmware/9_2_FPGA/tb/fir_sine_passband.csv diff --git a/9_Firmware/9_2_FPGA/tb/gen_mf_golden_ref.py b/firmware/9_2_FPGA/tb/gen_mf_golden_ref.py similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/gen_mf_golden_ref.py rename to firmware/9_2_FPGA/tb/gen_mf_golden_ref.py index 161e9d9..75783c3 100644 --- a/9_Firmware/9_2_FPGA/tb/gen_mf_golden_ref.py +++ b/firmware/9_2_FPGA/tb/gen_mf_golden_ref.py @@ -15,7 +15,7 @@ Each case produces 6 hex files (sig_i, sig_q, ref_i, ref_q, out_i, out_q) plus a human-readable summary file. Usage: - cd /Users/ganeshpanth/PLFM_RADAR/9_Firmware/9_2_FPGA/tb + cd /Users/ganeshpanth/PLFM_RADAR/firmware/9_2_FPGA/tb python3 gen_mf_golden_ref.py """ diff --git a/9_Firmware/9_2_FPGA/tb/golden/golden_doppler.mem b/firmware/9_2_FPGA/tb/golden/golden_doppler.mem similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/golden/golden_doppler.mem rename to firmware/9_2_FPGA/tb/golden/golden_doppler.mem diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_out_i_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_i_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_out_i_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_i_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_out_i_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_i_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_out_i_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_i_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_i_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_out_q_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_q_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_out_q_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_q_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_out_q_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_q_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_out_q_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_out_q_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_out_q_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_i_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_i_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_i_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_i_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_i_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_i_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_i_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_i_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_i_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_q_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_q_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_q_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_q_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_q_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_q_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_ref_q_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_ref_q_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_ref_q_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_i_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_i_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_i_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_i_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_i_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_i_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_i_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_i_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_i_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case1.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_q_case1.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case1.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_q_case1.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case2.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_q_case2.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case2.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_q_case2.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case3.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_q_case3.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case3.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_q_case3.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case4.hex b/firmware/9_2_FPGA/tb/mf_golden_sig_q_case4.hex similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_sig_q_case4.hex rename to firmware/9_2_FPGA/tb/mf_golden_sig_q_case4.hex diff --git a/9_Firmware/9_2_FPGA/tb/mf_golden_summary.txt b/firmware/9_2_FPGA/tb/mf_golden_summary.txt similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_golden_summary.txt rename to firmware/9_2_FPGA/tb/mf_golden_summary.txt diff --git a/9_Firmware/9_2_FPGA/tb/mf_pipeline_output.csv b/firmware/9_2_FPGA/tb/mf_pipeline_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/mf_pipeline_output.csv rename to firmware/9_2_FPGA/tb/mf_pipeline_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/nco_120mhz_output.csv b/firmware/9_2_FPGA/tb/nco_120mhz_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/nco_120mhz_output.csv rename to firmware/9_2_FPGA/tb/nco_120mhz_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/nco_1mhz_output.csv b/firmware/9_2_FPGA/tb/nco_1mhz_output.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/nco_1mhz_output.csv rename to firmware/9_2_FPGA/tb/nco_1mhz_output.csv diff --git a/9_Firmware/9_2_FPGA/tb/nco_freq_switch.csv b/firmware/9_2_FPGA/tb/nco_freq_switch.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/nco_freq_switch.csv rename to firmware/9_2_FPGA/tb/nco_freq_switch.csv diff --git a/9_Firmware/9_2_FPGA/tb/nco_quadrature.csv b/firmware/9_2_FPGA/tb/nco_quadrature.csv similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/nco_quadrature.csv rename to firmware/9_2_FPGA/tb/nco_quadrature.csv diff --git a/9_Firmware/9_2_FPGA/tb/radar_system_tb.v b/firmware/9_2_FPGA/tb/radar_system_tb.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/radar_system_tb.v rename to firmware/9_2_FPGA/tb/radar_system_tb.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_ad9484_xsim.v b/firmware/9_2_FPGA/tb/tb_ad9484_xsim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_ad9484_xsim.v rename to firmware/9_2_FPGA/tb/tb_ad9484_xsim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_cdc_modules.v b/firmware/9_2_FPGA/tb/tb_cdc_modules.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_cdc_modules.v rename to firmware/9_2_FPGA/tb/tb_cdc_modules.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_cfar_ca.v b/firmware/9_2_FPGA/tb/tb_cfar_ca.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_cfar_ca.v rename to firmware/9_2_FPGA/tb/tb_cfar_ca.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_chirp_contract.v b/firmware/9_2_FPGA/tb/tb_chirp_contract.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_chirp_contract.v rename to firmware/9_2_FPGA/tb/tb_chirp_contract.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_chirp_controller.v b/firmware/9_2_FPGA/tb/tb_chirp_controller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_chirp_controller.v rename to firmware/9_2_FPGA/tb/tb_chirp_controller.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_cic_decimator.v b/firmware/9_2_FPGA/tb/tb_cic_decimator.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_cic_decimator.v rename to firmware/9_2_FPGA/tb/tb_cic_decimator.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_ddc_400m.v b/firmware/9_2_FPGA/tb/tb_ddc_400m.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_ddc_400m.v rename to firmware/9_2_FPGA/tb/tb_ddc_400m.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_ddc_cosim.v b/firmware/9_2_FPGA/tb/tb_ddc_cosim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_ddc_cosim.v rename to firmware/9_2_FPGA/tb/tb_ddc_cosim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_ddc_input_interface.v b/firmware/9_2_FPGA/tb/tb_ddc_input_interface.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_ddc_input_interface.v rename to firmware/9_2_FPGA/tb/tb_ddc_input_interface.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_doppler_cosim.v b/firmware/9_2_FPGA/tb/tb_doppler_cosim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_doppler_cosim.v rename to firmware/9_2_FPGA/tb/tb_doppler_cosim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_doppler_realdata.v b/firmware/9_2_FPGA/tb/tb_doppler_realdata.v similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/tb_doppler_realdata.v rename to firmware/9_2_FPGA/tb/tb_doppler_realdata.v index e19e904..c895315 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_doppler_realdata.v +++ b/firmware/9_2_FPGA/tb/tb_doppler_realdata.v @@ -19,7 +19,7 @@ * -o tb/tb_doppler_realdata.vvp \ * tb/tb_doppler_realdata.v doppler_processor.v xfft_16.v fft_engine.v * - * Run from: 9_Firmware/9_2_FPGA/ + * Run from: firmware/9_2_FPGA/ * vvp tb/tb_doppler_realdata.vvp */ diff --git a/9_Firmware/9_2_FPGA/tb/tb_edge_detector.v b/firmware/9_2_FPGA/tb/tb_edge_detector.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_edge_detector.v rename to firmware/9_2_FPGA/tb/tb_edge_detector.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_fft_engine.v b/firmware/9_2_FPGA/tb/tb_fft_engine.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_fft_engine.v rename to firmware/9_2_FPGA/tb/tb_fft_engine.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_fir_lowpass.v b/firmware/9_2_FPGA/tb/tb_fir_lowpass.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_fir_lowpass.v rename to firmware/9_2_FPGA/tb/tb_fir_lowpass.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_fpga_self_test.v b/firmware/9_2_FPGA/tb/tb_fpga_self_test.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_fpga_self_test.v rename to firmware/9_2_FPGA/tb/tb_fpga_self_test.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_freq_matched_filter.v b/firmware/9_2_FPGA/tb/tb_freq_matched_filter.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_freq_matched_filter.v rename to firmware/9_2_FPGA/tb/tb_freq_matched_filter.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v b/firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v rename to firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v index 51e1d19..6407f97 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v +++ b/firmware/9_2_FPGA/tb/tb_fullchain_mti_cfar_realdata.v @@ -43,7 +43,7 @@ * range_bin_decimator.v mti_canceller.v doppler_processor.v \ * xfft_16.v fft_engine.v cfar_ca.v * - * Run from: 9_Firmware/9_2_FPGA/ + * Run from: firmware/9_2_FPGA/ * vvp tb/tb_fullchain_mti_cfar_realdata.vvp */ diff --git a/9_Firmware/9_2_FPGA/tb/tb_fullchain_realdata.v b/firmware/9_2_FPGA/tb/tb_fullchain_realdata.v similarity index 99% rename from 9_Firmware/9_2_FPGA/tb/tb_fullchain_realdata.v rename to firmware/9_2_FPGA/tb/tb_fullchain_realdata.v index af6003f..cf13ec8 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_fullchain_realdata.v +++ b/firmware/9_2_FPGA/tb/tb_fullchain_realdata.v @@ -29,7 +29,7 @@ * tb/tb_fullchain_realdata.v \ * range_bin_decimator.v doppler_processor.v xfft_16.v fft_engine.v * - * Run from: 9_Firmware/9_2_FPGA/ + * Run from: firmware/9_2_FPGA/ * vvp tb/tb_fullchain_realdata.vvp */ diff --git a/9_Firmware/9_2_FPGA/tb/tb_latency_buffer.v b/firmware/9_2_FPGA/tb/tb_latency_buffer.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_latency_buffer.v rename to firmware/9_2_FPGA/tb/tb_latency_buffer.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_matched_filter_processing_chain.v b/firmware/9_2_FPGA/tb/tb_matched_filter_processing_chain.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_matched_filter_processing_chain.v rename to firmware/9_2_FPGA/tb/tb_matched_filter_processing_chain.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_mf_chain_synth.v b/firmware/9_2_FPGA/tb/tb_mf_chain_synth.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_mf_chain_synth.v rename to firmware/9_2_FPGA/tb/tb_mf_chain_synth.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_mf_cosim.v b/firmware/9_2_FPGA/tb/tb_mf_cosim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_mf_cosim.v rename to firmware/9_2_FPGA/tb/tb_mf_cosim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_mti_canceller.v b/firmware/9_2_FPGA/tb/tb_mti_canceller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_mti_canceller.v rename to firmware/9_2_FPGA/tb/tb_mti_canceller.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_multiseg_cosim.v b/firmware/9_2_FPGA/tb/tb_multiseg_cosim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_multiseg_cosim.v rename to firmware/9_2_FPGA/tb/tb_multiseg_cosim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_nco_400m.v b/firmware/9_2_FPGA/tb/tb_nco_400m.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_nco_400m.v rename to firmware/9_2_FPGA/tb/tb_nco_400m.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_nco_xsim.v b/firmware/9_2_FPGA/tb/tb_nco_xsim.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_nco_xsim.v rename to firmware/9_2_FPGA/tb/tb_nco_xsim.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_radar_mode_controller.v b/firmware/9_2_FPGA/tb/tb_radar_mode_controller.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_radar_mode_controller.v rename to firmware/9_2_FPGA/tb/tb_radar_mode_controller.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v b/firmware/9_2_FPGA/tb/tb_radar_receiver_final.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v rename to firmware/9_2_FPGA/tb/tb_radar_receiver_final.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_range_bin_decimator.v b/firmware/9_2_FPGA/tb/tb_range_bin_decimator.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_range_bin_decimator.v rename to firmware/9_2_FPGA/tb/tb_range_bin_decimator.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_range_fft_realdata.v b/firmware/9_2_FPGA/tb/tb_range_fft_realdata.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_range_fft_realdata.v rename to firmware/9_2_FPGA/tb/tb_range_fft_realdata.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_rx_gain_control.v b/firmware/9_2_FPGA/tb/tb_rx_gain_control.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_rx_gain_control.v rename to firmware/9_2_FPGA/tb/tb_rx_gain_control.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_system_e2e.v b/firmware/9_2_FPGA/tb/tb_system_e2e.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_system_e2e.v rename to firmware/9_2_FPGA/tb/tb_system_e2e.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_threshold_detector.v b/firmware/9_2_FPGA/tb/tb_threshold_detector.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_threshold_detector.v rename to firmware/9_2_FPGA/tb/tb_threshold_detector.v diff --git a/9_Firmware/9_2_FPGA/tb/tb_usb_data_interface.v b/firmware/9_2_FPGA/tb/tb_usb_data_interface.v similarity index 100% rename from 9_Firmware/9_2_FPGA/tb/tb_usb_data_interface.v rename to firmware/9_2_FPGA/tb/tb_usb_data_interface.v diff --git a/9_Firmware/9_2_FPGA/usb_data_interface.v b/firmware/9_2_FPGA/usb_data_interface.v similarity index 100% rename from 9_Firmware/9_2_FPGA/usb_data_interface.v rename to firmware/9_2_FPGA/usb_data_interface.v diff --git a/9_Firmware/9_2_FPGA/usb_data_interface_ft2232h.v b/firmware/9_2_FPGA/usb_data_interface_ft2232h.v similarity index 100% rename from 9_Firmware/9_2_FPGA/usb_data_interface_ft2232h.v rename to firmware/9_2_FPGA/usb_data_interface_ft2232h.v diff --git a/9_Firmware/9_2_FPGA/xfft_16.v b/firmware/9_2_FPGA/xfft_16.v similarity index 100% rename from 9_Firmware/9_2_FPGA/xfft_16.v rename to firmware/9_2_FPGA/xfft_16.v diff --git a/9_Firmware/9_3_GUI/GUI_PyQt_Map.py b/firmware/9_3_GUI/GUI_PyQt_Map.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_PyQt_Map.py rename to firmware/9_3_GUI/GUI_PyQt_Map.py diff --git a/9_Firmware/9_3_GUI/GUI_V5.py b/firmware/9_3_GUI/GUI_V5.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V5.py rename to firmware/9_3_GUI/GUI_V5.py diff --git a/9_Firmware/9_3_GUI/GUI_V5_Demo.py b/firmware/9_3_GUI/GUI_V5_Demo.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V5_Demo.py rename to firmware/9_3_GUI/GUI_V5_Demo.py diff --git a/8_Utils/GUI_V6.gif b/firmware/9_3_GUI/GUI_V6.gif similarity index 100% rename from 8_Utils/GUI_V6.gif rename to firmware/9_3_GUI/GUI_V6.gif diff --git a/9_Firmware/9_3_GUI/GUI_V6.py b/firmware/9_3_GUI/GUI_V6.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V6.py rename to firmware/9_3_GUI/GUI_V6.py diff --git a/9_Firmware/9_3_GUI/GUI_V65_Tk.py b/firmware/9_3_GUI/GUI_V65_Tk.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V65_Tk.py rename to firmware/9_3_GUI/GUI_V65_Tk.py diff --git a/9_Firmware/9_3_GUI/GUI_V6_Demo.py b/firmware/9_3_GUI/GUI_V6_Demo.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V6_Demo.py rename to firmware/9_3_GUI/GUI_V6_Demo.py diff --git a/9_Firmware/9_3_GUI/GUI_V7_PyQt.py b/firmware/9_3_GUI/GUI_V7_PyQt.py similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V7_PyQt.py rename to firmware/9_3_GUI/GUI_V7_PyQt.py diff --git a/9_Firmware/9_3_GUI/GUI_versions.txt b/firmware/9_3_GUI/GUI_versions.txt similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_versions.txt rename to firmware/9_3_GUI/GUI_versions.txt diff --git a/9_Firmware/9_3_GUI/adi_agc_analysis.py b/firmware/9_3_GUI/adi_agc_analysis.py similarity index 100% rename from 9_Firmware/9_3_GUI/adi_agc_analysis.py rename to firmware/9_3_GUI/adi_agc_analysis.py diff --git a/9_Firmware/9_3_GUI/radar_protocol.py b/firmware/9_3_GUI/radar_protocol.py similarity index 100% rename from 9_Firmware/9_3_GUI/radar_protocol.py rename to firmware/9_3_GUI/radar_protocol.py diff --git a/9_Firmware/9_3_GUI/requirements_dashboard.txt b/firmware/9_3_GUI/requirements_dashboard.txt similarity index 100% rename from 9_Firmware/9_3_GUI/requirements_dashboard.txt rename to firmware/9_3_GUI/requirements_dashboard.txt diff --git a/9_Firmware/9_3_GUI/requirements_pyqt_gui.txt b/firmware/9_3_GUI/requirements_pyqt_gui.txt similarity index 100% rename from 9_Firmware/9_3_GUI/requirements_pyqt_gui.txt rename to firmware/9_3_GUI/requirements_pyqt_gui.txt diff --git a/9_Firmware/9_3_GUI/requirements_v7.txt b/firmware/9_3_GUI/requirements_v7.txt similarity index 100% rename from 9_Firmware/9_3_GUI/requirements_v7.txt rename to firmware/9_3_GUI/requirements_v7.txt diff --git a/9_Firmware/9_3_GUI/smoke_test.py b/firmware/9_3_GUI/smoke_test.py similarity index 100% rename from 9_Firmware/9_3_GUI/smoke_test.py rename to firmware/9_3_GUI/smoke_test.py diff --git a/9_Firmware/9_3_GUI/test_GUI_V65_Tk.py b/firmware/9_3_GUI/test_GUI_V65_Tk.py similarity index 100% rename from 9_Firmware/9_3_GUI/test_GUI_V65_Tk.py rename to firmware/9_3_GUI/test_GUI_V65_Tk.py diff --git a/8_Utils/Python/test_radar_data.csv b/firmware/9_3_GUI/test_radar_data.csv similarity index 100% rename from 8_Utils/Python/test_radar_data.csv rename to firmware/9_3_GUI/test_radar_data.csv diff --git a/9_Firmware/9_3_GUI/test_v7.py b/firmware/9_3_GUI/test_v7.py similarity index 100% rename from 9_Firmware/9_3_GUI/test_v7.py rename to firmware/9_3_GUI/test_v7.py diff --git a/9_Firmware/9_3_GUI/v7/__init__.py b/firmware/9_3_GUI/v7/__init__.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/__init__.py rename to firmware/9_3_GUI/v7/__init__.py diff --git a/9_Firmware/9_3_GUI/v7/agc_sim.py b/firmware/9_3_GUI/v7/agc_sim.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/agc_sim.py rename to firmware/9_3_GUI/v7/agc_sim.py diff --git a/9_Firmware/9_3_GUI/v7/dashboard.py b/firmware/9_3_GUI/v7/dashboard.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/dashboard.py rename to firmware/9_3_GUI/v7/dashboard.py diff --git a/9_Firmware/9_3_GUI/v7/hardware.py b/firmware/9_3_GUI/v7/hardware.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/hardware.py rename to firmware/9_3_GUI/v7/hardware.py diff --git a/9_Firmware/9_3_GUI/v7/map_widget.py b/firmware/9_3_GUI/v7/map_widget.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/map_widget.py rename to firmware/9_3_GUI/v7/map_widget.py diff --git a/9_Firmware/9_3_GUI/v7/models.py b/firmware/9_3_GUI/v7/models.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/models.py rename to firmware/9_3_GUI/v7/models.py diff --git a/9_Firmware/9_3_GUI/v7/processing.py b/firmware/9_3_GUI/v7/processing.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/processing.py rename to firmware/9_3_GUI/v7/processing.py diff --git a/9_Firmware/9_3_GUI/v7/replay.py b/firmware/9_3_GUI/v7/replay.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/replay.py rename to firmware/9_3_GUI/v7/replay.py diff --git a/9_Firmware/9_3_GUI/v7/software_fpga.py b/firmware/9_3_GUI/v7/software_fpga.py similarity index 99% rename from 9_Firmware/9_3_GUI/v7/software_fpga.py rename to firmware/9_3_GUI/v7/software_fpga.py index 9b0d669..be97cfd 100644 --- a/9_Firmware/9_3_GUI/v7/software_fpga.py +++ b/firmware/9_3_GUI/v7/software_fpga.py @@ -28,7 +28,7 @@ import numpy as np # Import golden_reference by adding the cosim path to sys.path # --------------------------------------------------------------------------- _GOLDEN_REF_DIR = str( - Path(__file__).resolve().parents[2] # 9_Firmware/ + Path(__file__).resolve().parents[2] # firmware/ / "9_2_FPGA" / "tb" / "cosim" / "real_data" ) if _GOLDEN_REF_DIR not in sys.path: diff --git a/9_Firmware/9_3_GUI/v7/workers.py b/firmware/9_3_GUI/v7/workers.py similarity index 100% rename from 9_Firmware/9_3_GUI/v7/workers.py rename to firmware/9_3_GUI/v7/workers.py diff --git a/9_Firmware/tests/cross_layer/.gitignore b/firmware/tests/cross_layer/.gitignore similarity index 100% rename from 9_Firmware/tests/cross_layer/.gitignore rename to firmware/tests/cross_layer/.gitignore diff --git a/9_Firmware/tests/cross_layer/adar1000_vm_reference.py b/firmware/tests/cross_layer/adar1000_vm_reference.py similarity index 98% rename from 9_Firmware/tests/cross_layer/adar1000_vm_reference.py rename to firmware/tests/cross_layer/adar1000_vm_reference.py index 0f897d7..554fca8 100644 --- a/9_Firmware/tests/cross_layer/adar1000_vm_reference.py +++ b/firmware/tests/cross_layer/adar1000_vm_reference.py @@ -1,7 +1,7 @@ """ADAR1000 vector-modulator ground-truth table and firmware parser. This module is a pure data + helpers library imported by the cross-layer -test suite (`9_Firmware/tests/cross_layer/test_cross_layer_contract.py`, +test suite (`firmware/tests/cross_layer/test_cross_layer_contract.py`, class `TestTier2Adar1000VmTableGroundTruth`). It has no CLI entry point and no side effects on import beyond the structural assertion on the table length. @@ -22,7 +22,7 @@ licensing-relevant source. PLFM_RADAR firmware indexing convention --------------------------------------- `adarSetRxPhase` / `adarSetTxPhase` in -`9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.cpp` +`firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.cpp` write `VM_I[phase % 128]` and `VM_Q[phase % 128]` to the chip. Each index N corresponds to commanded beam phase `N * 360/128 = N * 2.8125 deg`. The ADI table is also on a uniform 2.8125 deg grid (verified by diff --git a/9_Firmware/tests/cross_layer/contract_parser.py b/firmware/tests/cross_layer/contract_parser.py similarity index 100% rename from 9_Firmware/tests/cross_layer/contract_parser.py rename to firmware/tests/cross_layer/contract_parser.py diff --git a/9_Firmware/tests/cross_layer/stm32_settings_stub.cpp b/firmware/tests/cross_layer/stm32_settings_stub.cpp similarity index 93% rename from 9_Firmware/tests/cross_layer/stm32_settings_stub.cpp rename to firmware/tests/cross_layer/stm32_settings_stub.cpp index 853b327..479dab1 100644 --- a/9_Firmware/tests/cross_layer/stm32_settings_stub.cpp +++ b/firmware/tests/cross_layer/stm32_settings_stub.cpp @@ -7,8 +7,8 @@ * all parsed field=value pairs to stdout. * * Compile: c++ -std=c++11 -o stm32_settings_stub stm32_settings_stub.cpp \ - * ../../9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp \ - * -I../../9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ + * ../../firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/RadarSettings.cpp \ + * -I../../firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ * * Usage: ./stm32_settings_stub packet.bin * Prints: field=value lines (one per field) diff --git a/9_Firmware/tests/cross_layer/tb_cross_layer_ft2232h.v b/firmware/tests/cross_layer/tb_cross_layer_ft2232h.v similarity index 100% rename from 9_Firmware/tests/cross_layer/tb_cross_layer_ft2232h.v rename to firmware/tests/cross_layer/tb_cross_layer_ft2232h.v diff --git a/9_Firmware/tests/cross_layer/test_cross_layer_contract.py b/firmware/tests/cross_layer/test_cross_layer_contract.py similarity index 99% rename from 9_Firmware/tests/cross_layer/test_cross_layer_contract.py rename to firmware/tests/cross_layer/test_cross_layer_contract.py index 53b1554..fe9f1cd 100644 --- a/9_Firmware/tests/cross_layer/test_cross_layer_contract.py +++ b/firmware/tests/cross_layer/test_cross_layer_contract.py @@ -744,7 +744,7 @@ class TestTier1STM32SettingsPacket: # # Cross-layer contract: the firmware constants # ADAR1000Manager::VM_I[128] / VM_Q[128] -# (in 9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.cpp) +# (in firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADAR1000_Manager.cpp) # MUST equal the byte values published in the ADAR1000 datasheet Rev. B, # Tables 13-16 page 34 ("Phase Shifter Programming"), on a uniform 2.8125 deg # grid (index N == phase N * 360/128 deg). diff --git a/9_Firmware/tools/uart_capture.py b/firmware/tools/uart_capture.py similarity index 100% rename from 9_Firmware/tools/uart_capture.py rename to firmware/tools/uart_capture.py diff --git a/6_Application Notes/UG-290.pdf b/hardware/application-notes/UG-290.pdf similarity index 100% rename from 6_Application Notes/UG-290.pdf rename to hardware/application-notes/UG-290.pdf diff --git a/1_Project_Description/Project_Description.docx b/hardware/description/Project_Description.docx similarity index 100% rename from 1_Project_Description/Project_Description.docx rename to hardware/description/Project_Description.docx diff --git a/2_Functional Diagram & Interconnection Matrices/RADAR_V6.drawio b/hardware/diagrams/RADAR_V6.drawio similarity index 100% rename from 2_Functional Diagram & Interconnection Matrices/RADAR_V6.drawio rename to hardware/diagrams/RADAR_V6.drawio diff --git a/2_Functional Diagram & Interconnection Matrices/RADAR_V6.jpg b/hardware/diagrams/RADAR_V6.jpg similarity index 100% rename from 2_Functional Diagram & Interconnection Matrices/RADAR_V6.jpg rename to hardware/diagrams/RADAR_V6.jpg diff --git a/2_Functional Diagram & Interconnection Matrices/RADAR_V6_V2.png b/hardware/diagrams/RADAR_V6_V2.png similarity index 100% rename from 2_Functional Diagram & Interconnection Matrices/RADAR_V6_V2.png rename to hardware/diagrams/RADAR_V6_V2.png diff --git a/8_Utils/0044.jpg b/hardware/mechanical/0044.jpg similarity index 100% rename from 8_Utils/0044.jpg rename to hardware/mechanical/0044.jpg diff --git a/8_Utils/3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg b/hardware/mechanical/3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg similarity index 100% rename from 8_Utils/3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg rename to hardware/mechanical/3fb1dabf-2c6d-4b5d-b471-48bc461ce914.jpg diff --git a/8_Utils/AERIS-10_RADAR.png b/hardware/mechanical/AERIS-10_RADAR.png similarity index 100% rename from 8_Utils/AERIS-10_RADAR.png rename to hardware/mechanical/AERIS-10_RADAR.png diff --git a/8_Utils/Antenna_Array.jpg b/hardware/mechanical/Antenna_Array.jpg similarity index 100% rename from 8_Utils/Antenna_Array.jpg rename to hardware/mechanical/Antenna_Array.jpg diff --git a/8_Utils/Eagle_ CAD_Libs/142-0731-211.lbr b/hardware/mechanical/Eagle_ CAD_Libs/142-0731-211.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/142-0731-211.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/142-0731-211.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/AD9523BCPZ.lbr b/hardware/mechanical/Eagle_ CAD_Libs/AD9523BCPZ.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/AD9523BCPZ.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/AD9523BCPZ.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/AFII-TC-0015.lbr b/hardware/mechanical/Eagle_ CAD_Libs/AFII-TC-0015.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/AFII-TC-0015.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/AFII-TC-0015.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/Air_Link.lbr b/hardware/mechanical/Eagle_ CAD_Libs/Air_Link.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/Air_Link.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/Air_Link.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/CONMCX013.lbr b/hardware/mechanical/Eagle_ CAD_Libs/CONMCX013.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/CONMCX013.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/CONMCX013.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr b/hardware/mechanical/Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/Eagle_WR-SMP_rev21a.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/My_Library.lbr b/hardware/mechanical/Eagle_ CAD_Libs/My_Library.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/My_Library.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/My_Library.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/My_Library_2.lbr b/hardware/mechanical/Eagle_ CAD_Libs/My_Library_2.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/My_Library_2.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/My_Library_2.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/My_Library_RADAR.lbr b/hardware/mechanical/Eagle_ CAD_Libs/My_Library_RADAR.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/My_Library_RADAR.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/My_Library_RADAR.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/My_Library_SDR.lbr b/hardware/mechanical/Eagle_ CAD_Libs/My_Library_SDR.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/My_Library_SDR.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/My_Library_SDR.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/NRF905.lbr b/hardware/mechanical/Eagle_ CAD_Libs/NRF905.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/NRF905.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/NRF905.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/QPA2811.lbr b/hardware/mechanical/Eagle_ CAD_Libs/QPA2811.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/QPA2811.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/QPA2811.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/SF2321D.lbr b/hardware/mechanical/Eagle_ CAD_Libs/SF2321D.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/SF2321D.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/SF2321D.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr b/hardware/mechanical/Eagle_ CAD_Libs/Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/Trans_Wolfspeed_CGH40006P_eec_IPC_A.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr b/hardware/mechanical/Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/XC7A100T-1FGG484C.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr b/hardware/mechanical/Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/XC7A50T-2CPG236I.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr b/hardware/mechanical/Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/XC7A50T-2FTG256I.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr b/hardware/mechanical/Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/XC7S50-1CSGA324C.lbr diff --git a/8_Utils/Eagle_ CAD_Libs/mmWAVE.lbr b/hardware/mechanical/Eagle_ CAD_Libs/mmWAVE.lbr similarity index 100% rename from 8_Utils/Eagle_ CAD_Libs/mmWAVE.lbr rename to hardware/mechanical/Eagle_ CAD_Libs/mmWAVE.lbr diff --git a/8_Utils/GUI.jpg b/hardware/mechanical/GUI.jpg similarity index 100% rename from 8_Utils/GUI.jpg rename to hardware/mechanical/GUI.jpg diff --git a/9_Firmware/9_3_GUI/GUI_V6.gif b/hardware/mechanical/GUI_V6.gif similarity index 100% rename from 9_Firmware/9_3_GUI/GUI_V6.gif rename to hardware/mechanical/GUI_V6.gif diff --git a/8_Utils/Mechanical_Drawings/Down_Part_Waveguide.dwg b/hardware/mechanical/Mechanical_Drawings/Down_Part_Waveguide.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Down_Part_Waveguide.dwg rename to hardware/mechanical/Mechanical_Drawings/Down_Part_Waveguide.dwg diff --git a/8_Utils/Mechanical_Drawings/Enclosure.bak b/hardware/mechanical/Mechanical_Drawings/Enclosure.bak similarity index 100% rename from 8_Utils/Mechanical_Drawings/Enclosure.bak rename to hardware/mechanical/Mechanical_Drawings/Enclosure.bak diff --git a/8_Utils/Mechanical_Drawings/Enclosure.dwg b/hardware/mechanical/Mechanical_Drawings/Enclosure.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Enclosure.dwg rename to hardware/mechanical/Mechanical_Drawings/Enclosure.dwg diff --git a/8_Utils/Mechanical_Drawings/Heat_Sink_Main_Board.dwg b/hardware/mechanical/Mechanical_Drawings/Heat_Sink_Main_Board.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Heat_Sink_Main_Board.dwg rename to hardware/mechanical/Mechanical_Drawings/Heat_Sink_Main_Board.dwg diff --git a/8_Utils/Mechanical_Drawings/Heat_Sink_PA.dwg b/hardware/mechanical/Mechanical_Drawings/Heat_Sink_PA.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Heat_Sink_PA.dwg rename to hardware/mechanical/Mechanical_Drawings/Heat_Sink_PA.dwg diff --git a/8_Utils/Mechanical_Drawings/RADAR_V1.bak b/hardware/mechanical/Mechanical_Drawings/RADAR_V1.bak similarity index 100% rename from 8_Utils/Mechanical_Drawings/RADAR_V1.bak rename to hardware/mechanical/Mechanical_Drawings/RADAR_V1.bak diff --git a/8_Utils/Mechanical_Drawings/RADAR_V1.dwg b/hardware/mechanical/Mechanical_Drawings/RADAR_V1.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/RADAR_V1.dwg rename to hardware/mechanical/Mechanical_Drawings/RADAR_V1.dwg diff --git a/8_Utils/Mechanical_Drawings/SlipRing.dwg b/hardware/mechanical/Mechanical_Drawings/SlipRing.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/SlipRing.dwg rename to hardware/mechanical/Mechanical_Drawings/SlipRing.dwg diff --git a/8_Utils/Mechanical_Drawings/Upper_Part_Waveguide.dwg b/hardware/mechanical/Mechanical_Drawings/Upper_Part_Waveguide.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Upper_Part_Waveguide.dwg rename to hardware/mechanical/Mechanical_Drawings/Upper_Part_Waveguide.dwg diff --git a/8_Utils/Mechanical_Drawings/Waveguide.dwg b/hardware/mechanical/Mechanical_Drawings/Waveguide.dwg similarity index 100% rename from 8_Utils/Mechanical_Drawings/Waveguide.dwg rename to hardware/mechanical/Mechanical_Drawings/Waveguide.dwg diff --git a/8_Utils/Nawfal.png b/hardware/mechanical/Nawfal.png similarity index 100% rename from 8_Utils/Nawfal.png rename to hardware/mechanical/Nawfal.png diff --git a/8_Utils/PCBWAY.jpg b/hardware/mechanical/PCBWAY.jpg similarity index 100% rename from 8_Utils/PCBWAY.jpg rename to hardware/mechanical/PCBWAY.jpg diff --git a/8_Utils/Python/CSV_radar.py b/hardware/mechanical/Python/CSV_radar.py similarity index 100% rename from 8_Utils/Python/CSV_radar.py rename to hardware/mechanical/Python/CSV_radar.py diff --git a/8_Utils/Python/CSV_radar_2.py b/hardware/mechanical/Python/CSV_radar_2.py similarity index 100% rename from 8_Utils/Python/CSV_radar_2.py rename to hardware/mechanical/Python/CSV_radar_2.py diff --git a/8_Utils/Python/FFT_Ramp_Frequency.py b/hardware/mechanical/Python/FFT_Ramp_Frequency.py similarity index 100% rename from 8_Utils/Python/FFT_Ramp_Frequency.py rename to hardware/mechanical/Python/FFT_Ramp_Frequency.py diff --git a/8_Utils/Python/Gen_Triangular.py b/hardware/mechanical/Python/Gen_Triangular.py similarity index 100% rename from 8_Utils/Python/Gen_Triangular.py rename to hardware/mechanical/Python/Gen_Triangular.py diff --git a/8_Utils/Python/Generic_Ramp_Frequency.py b/hardware/mechanical/Python/Generic_Ramp_Frequency.py similarity index 100% rename from 8_Utils/Python/Generic_Ramp_Frequency.py rename to hardware/mechanical/Python/Generic_Ramp_Frequency.py diff --git a/8_Utils/Python/Generic_Triangular_Frequency.py b/hardware/mechanical/Python/Generic_Triangular_Frequency.py similarity index 100% rename from 8_Utils/Python/Generic_Triangular_Frequency.py rename to hardware/mechanical/Python/Generic_Triangular_Frequency.py diff --git a/8_Utils/Python/LUT.py b/hardware/mechanical/Python/LUT.py similarity index 100% rename from 8_Utils/Python/LUT.py rename to hardware/mechanical/Python/LUT.py diff --git a/8_Utils/Python/RADAR_eq.py b/hardware/mechanical/Python/RADAR_eq.py similarity index 100% rename from 8_Utils/Python/RADAR_eq.py rename to hardware/mechanical/Python/RADAR_eq.py diff --git a/8_Utils/Python/Ramp_Frequency.py b/hardware/mechanical/Python/Ramp_Frequency.py similarity index 100% rename from 8_Utils/Python/Ramp_Frequency.py rename to hardware/mechanical/Python/Ramp_Frequency.py diff --git a/8_Utils/Python/patch_antenna.py b/hardware/mechanical/Python/patch_antenna.py similarity index 100% rename from 8_Utils/Python/patch_antenna.py rename to hardware/mechanical/Python/patch_antenna.py diff --git a/8_Utils/Python/small_test_radar_data.csv b/hardware/mechanical/Python/small_test_radar_data.csv similarity index 100% rename from 8_Utils/Python/small_test_radar_data.csv rename to hardware/mechanical/Python/small_test_radar_data.csv diff --git a/9_Firmware/9_3_GUI/test_radar_data.csv b/hardware/mechanical/Python/test_radar_data.csv similarity index 100% rename from 9_Firmware/9_3_GUI/test_radar_data.csv rename to hardware/mechanical/Python/test_radar_data.csv diff --git a/8_Utils/RADAR_V6_V2.jpg b/hardware/mechanical/RADAR_V6_V2.jpg similarity index 100% rename from 8_Utils/RADAR_V6_V2.jpg rename to hardware/mechanical/RADAR_V6_V2.jpg diff --git a/8_Utils/RADAR_V6_V2.png b/hardware/mechanical/RADAR_V6_V2.png similarity index 100% rename from 8_Utils/RADAR_V6_V2.png rename to hardware/mechanical/RADAR_V6_V2.png diff --git a/8_Utils/SplitRing_test.mp4 b/hardware/mechanical/SplitRing_test.mp4 similarity index 100% rename from 8_Utils/SplitRing_test.mp4 rename to hardware/mechanical/SplitRing_test.mp4 diff --git a/8_Utils/b79a6fe3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg b/hardware/mechanical/b79a6fe3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg similarity index 100% rename from 8_Utils/b79a6fe3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg rename to hardware/mechanical/b79a6fe3-5abf-473d-b3e2-178e6a9cf4da - Copie.jpg diff --git a/3_Power Management/Power Management V6.xlsx b/hardware/power/Power Management V6.xlsx similarity index 100% rename from 3_Power Management/Power Management V6.xlsx rename to hardware/power/Power Management V6.xlsx diff --git a/5_Simulations/AAF_openEMS/aaf_simulation.py b/hardware/rf-simulations/AAF_openEMS/aaf_simulation.py similarity index 100% rename from 5_Simulations/AAF_openEMS/aaf_simulation.py rename to hardware/rf-simulations/AAF_openEMS/aaf_simulation.py diff --git a/5_Simulations/Antenna/Quartz_Waveguide.py b/hardware/rf-simulations/Antenna/Quartz_Waveguide.py similarity index 100% rename from 5_Simulations/Antenna/Quartz_Waveguide.py rename to hardware/rf-simulations/Antenna/Quartz_Waveguide.py diff --git a/5_Simulations/Antenna/openems_quartz_slotted_wg_10p5GHz.py b/hardware/rf-simulations/Antenna/openems_quartz_slotted_wg_10p5GHz.py similarity index 100% rename from 5_Simulations/Antenna/openems_quartz_slotted_wg_10p5GHz.py rename to hardware/rf-simulations/Antenna/openems_quartz_slotted_wg_10p5GHz.py diff --git a/5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.dat b/hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.dat similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.dat rename to hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.dat diff --git a/5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.dpl b/hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.dpl similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.dpl rename to hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.dpl diff --git a/5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.sch b/hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.sch similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/DAC_RLPF.sch rename to hardware/rf-simulations/DAC_ReconstructionFilter/DAC_RLPF.sch diff --git a/5_Simulations/DAC_ReconstructionFilter/Generate_ChirpcsvFile.py b/hardware/rf-simulations/DAC_ReconstructionFilter/Generate_ChirpcsvFile.py similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/Generate_ChirpcsvFile.py rename to hardware/rf-simulations/DAC_ReconstructionFilter/Generate_ChirpcsvFile.py diff --git a/5_Simulations/DAC_ReconstructionFilter/dac_output.csv b/hardware/rf-simulations/DAC_ReconstructionFilter/dac_output.csv similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/dac_output.csv rename to hardware/rf-simulations/DAC_ReconstructionFilter/dac_output.csv diff --git a/5_Simulations/DAC_ReconstructionFilter/multi_ramp_output.csv b/hardware/rf-simulations/DAC_ReconstructionFilter/multi_ramp_output.csv similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/multi_ramp_output.csv rename to hardware/rf-simulations/DAC_ReconstructionFilter/multi_ramp_output.csv diff --git a/5_Simulations/DAC_ReconstructionFilter/multi_ramp_stairs.csv b/hardware/rf-simulations/DAC_ReconstructionFilter/multi_ramp_stairs.csv similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/multi_ramp_stairs.csv rename to hardware/rf-simulations/DAC_ReconstructionFilter/multi_ramp_stairs.csv diff --git a/5_Simulations/DAC_ReconstructionFilter/ramp_output.csv b/hardware/rf-simulations/DAC_ReconstructionFilter/ramp_output.csv similarity index 100% rename from 5_Simulations/DAC_ReconstructionFilter/ramp_output.csv rename to hardware/rf-simulations/DAC_ReconstructionFilter/ramp_output.csv diff --git a/5_Simulations/E_plane_Kaiser25dB_like.png b/hardware/rf-simulations/E_plane_Kaiser25dB_like.png similarity index 100% rename from 5_Simulations/E_plane_Kaiser25dB_like.png rename to hardware/rf-simulations/E_plane_Kaiser25dB_like.png diff --git a/5_Simulations/E_plane_cut.png b/hardware/rf-simulations/E_plane_cut.png similarity index 100% rename from 5_Simulations/E_plane_cut.png rename to hardware/rf-simulations/E_plane_cut.png diff --git a/5_Simulations/Fencing/Via_fencing.py b/hardware/rf-simulations/Fencing/Via_fencing.py similarity index 100% rename from 5_Simulations/Fencing/Via_fencing.py rename to hardware/rf-simulations/Fencing/Via_fencing.py diff --git a/5_Simulations/Fencing/Via_fencing2.py b/hardware/rf-simulations/Fencing/Via_fencing2.py similarity index 100% rename from 5_Simulations/Fencing/Via_fencing2.py rename to hardware/rf-simulations/Fencing/Via_fencing2.py diff --git a/5_Simulations/Fencing/via_fence_setup_pitch.png b/hardware/rf-simulations/Fencing/via_fence_setup_pitch.png similarity index 100% rename from 5_Simulations/Fencing/via_fence_setup_pitch.png rename to hardware/rf-simulations/Fencing/via_fence_setup_pitch.png diff --git a/5_Simulations/Fencing/via_fence_setup_pitch_offset.png b/hardware/rf-simulations/Fencing/via_fence_setup_pitch_offset.png similarity index 100% rename from 5_Simulations/Fencing/via_fence_setup_pitch_offset.png rename to hardware/rf-simulations/Fencing/via_fence_setup_pitch_offset.png diff --git a/5_Simulations/H_plane_Kaiser25dB_like.png b/hardware/rf-simulations/H_plane_Kaiser25dB_like.png similarity index 100% rename from 5_Simulations/H_plane_Kaiser25dB_like.png rename to hardware/rf-simulations/H_plane_Kaiser25dB_like.png diff --git a/5_Simulations/H_plane_cut.png b/hardware/rf-simulations/H_plane_cut.png similarity index 100% rename from 5_Simulations/H_plane_cut.png rename to hardware/rf-simulations/H_plane_cut.png diff --git a/5_Simulations/Heatmap_Kaiser25dB_like.png b/hardware/rf-simulations/Heatmap_Kaiser25dB_like.png similarity index 100% rename from 5_Simulations/Heatmap_Kaiser25dB_like.png rename to hardware/rf-simulations/Heatmap_Kaiser25dB_like.png diff --git a/5_Simulations/IF_BPF/IF_BPF.dat b/hardware/rf-simulations/IF_BPF/IF_BPF.dat similarity index 100% rename from 5_Simulations/IF_BPF/IF_BPF.dat rename to hardware/rf-simulations/IF_BPF/IF_BPF.dat diff --git a/5_Simulations/IF_BPF/IF_BPF.dpl b/hardware/rf-simulations/IF_BPF/IF_BPF.dpl similarity index 100% rename from 5_Simulations/IF_BPF/IF_BPF.dpl rename to hardware/rf-simulations/IF_BPF/IF_BPF.dpl diff --git a/5_Simulations/IF_BPF/IF_BPF.sch b/hardware/rf-simulations/IF_BPF/IF_BPF.sch similarity index 100% rename from 5_Simulations/IF_BPF/IF_BPF.sch rename to hardware/rf-simulations/IF_BPF/IF_BPF.sch diff --git a/5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.dat b/hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.dat similarity index 100% rename from 5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.dat rename to hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.dat diff --git a/5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.dpl b/hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.dpl similarity index 100% rename from 5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.dpl rename to hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.dpl diff --git a/5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.sch b/hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.sch similarity index 100% rename from 5_Simulations/IF_BPF_Balanced/IF_BPF_Balanced.sch rename to hardware/rf-simulations/IF_BPF_Balanced/IF_BPF_Balanced.sch diff --git a/5_Simulations/IF_BPF_Balanced/multiband_signal.csv b/hardware/rf-simulations/IF_BPF_Balanced/multiband_signal.csv similarity index 100% rename from 5_Simulations/IF_BPF_Balanced/multiband_signal.csv rename to hardware/rf-simulations/IF_BPF_Balanced/multiband_signal.csv diff --git a/5_Simulations/IF_BPF_Balanced/six_tone_signal.csv b/hardware/rf-simulations/IF_BPF_Balanced/six_tone_signal.csv similarity index 100% rename from 5_Simulations/IF_BPF_Balanced/six_tone_signal.csv rename to hardware/rf-simulations/IF_BPF_Balanced/six_tone_signal.csv diff --git a/5_Simulations/Matlab/16_8.m b/hardware/rf-simulations/Matlab/16_8.m similarity index 100% rename from 5_Simulations/Matlab/16_8.m rename to hardware/rf-simulations/Matlab/16_8.m diff --git a/5_Simulations/Matlab/Antenna16_8.m b/hardware/rf-simulations/Matlab/Antenna16_8.m similarity index 100% rename from 5_Simulations/Matlab/Antenna16_8.m rename to hardware/rf-simulations/Matlab/Antenna16_8.m diff --git a/5_Simulations/Matlab/Antenna_array.m b/hardware/rf-simulations/Matlab/Antenna_array.m similarity index 100% rename from 5_Simulations/Matlab/Antenna_array.m rename to hardware/rf-simulations/Matlab/Antenna_array.m diff --git a/5_Simulations/Matlab/DielectricCatalog.csv b/hardware/rf-simulations/Matlab/DielectricCatalog.csv similarity index 100% rename from 5_Simulations/Matlab/DielectricCatalog.csv rename to hardware/rf-simulations/Matlab/DielectricCatalog.csv diff --git a/5_Simulations/Matlab/antenna16_antenna8.m b/hardware/rf-simulations/Matlab/antenna16_antenna8.m similarity index 100% rename from 5_Simulations/Matlab/antenna16_antenna8.m rename to hardware/rf-simulations/Matlab/antenna16_antenna8.m diff --git a/5_Simulations/Matlab/pattern_data.mat b/hardware/rf-simulations/Matlab/pattern_data.mat similarity index 100% rename from 5_Simulations/Matlab/pattern_data.mat rename to hardware/rf-simulations/Matlab/pattern_data.mat diff --git a/5_Simulations/QPA2962.dat b/hardware/rf-simulations/QPA2962.dat similarity index 100% rename from 5_Simulations/QPA2962.dat rename to hardware/rf-simulations/QPA2962.dat diff --git a/5_Simulations/QPA2962.dpl b/hardware/rf-simulations/QPA2962.dpl similarity index 100% rename from 5_Simulations/QPA2962.dpl rename to hardware/rf-simulations/QPA2962.dpl diff --git a/5_Simulations/QPA2962.sch b/hardware/rf-simulations/QPA2962.sch similarity index 100% rename from 5_Simulations/QPA2962.sch rename to hardware/rf-simulations/QPA2962.sch diff --git a/5_Simulations/RF switch/Impedance.dat b/hardware/rf-simulations/RF switch/Impedance.dat similarity index 100% rename from 5_Simulations/RF switch/Impedance.dat rename to hardware/rf-simulations/RF switch/Impedance.dat diff --git a/5_Simulations/RF switch/Impedance.dpl b/hardware/rf-simulations/RF switch/Impedance.dpl similarity index 100% rename from 5_Simulations/RF switch/Impedance.dpl rename to hardware/rf-simulations/RF switch/Impedance.dpl diff --git a/5_Simulations/RF switch/Impedance.sch b/hardware/rf-simulations/RF switch/Impedance.sch similarity index 100% rename from 5_Simulations/RF switch/Impedance.sch rename to hardware/rf-simulations/RF switch/Impedance.sch diff --git a/5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p b/hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p similarity index 100% rename from 5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p rename to hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_100MHz_Plus25DegC_UNIT1.s3p diff --git a/5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p b/hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p similarity index 100% rename from 5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p rename to hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF1 ON_40GHz_Plus25DegC_UNIT1.s3p diff --git a/5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p b/hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p similarity index 100% rename from 5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p rename to hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_100MHz_Plus25DegC_UNIT1.s3p diff --git a/5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p b/hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p similarity index 100% rename from 5_Simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p rename to hardware/rf-simulations/RF switch/Sparameters/M3SWA2-34DR+_3.5V_RF2 ON_40GHz_Plus25DegC_UNIT1.s3p diff --git a/5_Simulations/Sim_BPF_Te_100um/Drawing1.bak b/hardware/rf-simulations/Sim_BPF_Te_100um/Drawing1.bak similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Drawing1.bak rename to hardware/rf-simulations/Sim_BPF_Te_100um/Drawing1.bak diff --git a/5_Simulations/Sim_BPF_Te_100um/Drawing1.dxf b/hardware/rf-simulations/Sim_BPF_Te_100um/Drawing1.dxf similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Drawing1.dxf rename to hardware/rf-simulations/Sim_BPF_Te_100um/Drawing1.dxf diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber-backups/Gerber-2025-09-21_024138.zip b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber-backups/Gerber-2025-09-21_024138.zip similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber-backups/Gerber-2025-09-21_024138.zip rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber-backups/Gerber-2025-09-21_024138.zip diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pcb diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_prl diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_pro diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/Gerber.kicad_sch diff --git a/5_Simulations/Sim_BPF_Te_100um/Gerber/fp-info-cache b/hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/fp-info-cache similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Gerber/fp-info-cache rename to hardware/rf-simulations/Sim_BPF_Te_100um/Gerber/fp-info-cache diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dat diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.dpl diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.gds diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.ite diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.net b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.net similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.net rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.net diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pcb diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.pdf diff --git a/5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch b/hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch rename to hardware/rf-simulations/Sim_BPF_Te_100um/Sim_BPF_Te_100um.sch diff --git a/5_Simulations/Sim_BPF_Te_100um/gerber_file.gbr b/hardware/rf-simulations/Sim_BPF_Te_100um/gerber_file.gbr similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/gerber_file.gbr rename to hardware/rf-simulations/Sim_BPF_Te_100um/gerber_file.gbr diff --git a/5_Simulations/Sim_BPF_Te_100um/qucs2grb_log.txt b/hardware/rf-simulations/Sim_BPF_Te_100um/qucs2grb_log.txt similarity index 100% rename from 5_Simulations/Sim_BPF_Te_100um/qucs2grb_log.txt rename to hardware/rf-simulations/Sim_BPF_Te_100um/qucs2grb_log.txt diff --git a/5_Simulations/Slotted_DielectricFilled_Waveguide.m b/hardware/rf-simulations/Slotted_DielectricFilled_Waveguide.m similarity index 100% rename from 5_Simulations/Slotted_DielectricFilled_Waveguide.m rename to hardware/rf-simulations/Slotted_DielectricFilled_Waveguide.m diff --git a/5_Simulations/Stub_BPF/Stub_BPF.dat b/hardware/rf-simulations/Stub_BPF/Stub_BPF.dat similarity index 100% rename from 5_Simulations/Stub_BPF/Stub_BPF.dat rename to hardware/rf-simulations/Stub_BPF/Stub_BPF.dat diff --git a/5_Simulations/Stub_BPF/Stub_BPF.net b/hardware/rf-simulations/Stub_BPF/Stub_BPF.net similarity index 100% rename from 5_Simulations/Stub_BPF/Stub_BPF.net rename to hardware/rf-simulations/Stub_BPF/Stub_BPF.net diff --git a/5_Simulations/Stub_BPF/Stub_BPF.sch b/hardware/rf-simulations/Stub_BPF/Stub_BPF.sch similarity index 100% rename from 5_Simulations/Stub_BPF/Stub_BPF.sch rename to hardware/rf-simulations/Stub_BPF/Stub_BPF.sch diff --git a/5_Simulations/Stub_BPF_V5.dat b/hardware/rf-simulations/Stub_BPF_V5.dat similarity index 100% rename from 5_Simulations/Stub_BPF_V5.dat rename to hardware/rf-simulations/Stub_BPF_V5.dat diff --git a/5_Simulations/Stub_BPF_V5.dpl b/hardware/rf-simulations/Stub_BPF_V5.dpl similarity index 100% rename from 5_Simulations/Stub_BPF_V5.dpl rename to hardware/rf-simulations/Stub_BPF_V5.dpl diff --git a/5_Simulations/Stub_BPF_V5.sch b/hardware/rf-simulations/Stub_BPF_V5.sch similarity index 100% rename from 5_Simulations/Stub_BPF_V5.sch rename to hardware/rf-simulations/Stub_BPF_V5.sch diff --git a/5_Simulations/array_pattern_Kaiser25dB_like.py b/hardware/rf-simulations/array_pattern_Kaiser25dB_like.py similarity index 100% rename from 5_Simulations/array_pattern_Kaiser25dB_like.py rename to hardware/rf-simulations/array_pattern_Kaiser25dB_like.py diff --git a/5_Simulations/array_pattern_heatmap.png b/hardware/rf-simulations/array_pattern_heatmap.png similarity index 100% rename from 5_Simulations/array_pattern_heatmap.png rename to hardware/rf-simulations/array_pattern_heatmap.png diff --git a/5_Simulations/sim_wg_alumina_32/et b/hardware/rf-simulations/sim_wg_alumina_32/et similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/et rename to hardware/rf-simulations/sim_wg_alumina_32/et diff --git a/5_Simulations/sim_wg_alumina_32/ht b/hardware/rf-simulations/sim_wg_alumina_32/ht similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/ht rename to hardware/rf-simulations/sim_wg_alumina_32/ht diff --git a/5_Simulations/sim_wg_alumina_32/port_it1A b/hardware/rf-simulations/sim_wg_alumina_32/port_it1A similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/port_it1A rename to hardware/rf-simulations/sim_wg_alumina_32/port_it1A diff --git a/5_Simulations/sim_wg_alumina_32/port_it1B b/hardware/rf-simulations/sim_wg_alumina_32/port_it1B similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/port_it1B rename to hardware/rf-simulations/sim_wg_alumina_32/port_it1B diff --git a/5_Simulations/sim_wg_alumina_32/port_ut1A b/hardware/rf-simulations/sim_wg_alumina_32/port_ut1A similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/port_ut1A rename to hardware/rf-simulations/sim_wg_alumina_32/port_ut1A diff --git a/5_Simulations/sim_wg_alumina_32/port_ut1B b/hardware/rf-simulations/sim_wg_alumina_32/port_ut1B similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/port_ut1B rename to hardware/rf-simulations/sim_wg_alumina_32/port_ut1B diff --git a/5_Simulations/sim_wg_alumina_32/port_ut1C b/hardware/rf-simulations/sim_wg_alumina_32/port_ut1C similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/port_ut1C rename to hardware/rf-simulations/sim_wg_alumina_32/port_ut1C diff --git a/5_Simulations/sim_wg_alumina_32/wg_alumina_32.xml b/hardware/rf-simulations/sim_wg_alumina_32/wg_alumina_32.xml similarity index 100% rename from 5_Simulations/sim_wg_alumina_32/wg_alumina_32.xml rename to hardware/rf-simulations/sim_wg_alumina_32/wg_alumina_32.xml diff --git a/5_Simulations/sim_wg_alumina_fast/et b/hardware/rf-simulations/sim_wg_alumina_fast/et similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/et rename to hardware/rf-simulations/sim_wg_alumina_fast/et diff --git a/5_Simulations/sim_wg_alumina_fast/ht b/hardware/rf-simulations/sim_wg_alumina_fast/ht similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/ht rename to hardware/rf-simulations/sim_wg_alumina_fast/ht diff --git a/5_Simulations/sim_wg_alumina_fast/port_it1A b/hardware/rf-simulations/sim_wg_alumina_fast/port_it1A similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/port_it1A rename to hardware/rf-simulations/sim_wg_alumina_fast/port_it1A diff --git a/5_Simulations/sim_wg_alumina_fast/port_it1B b/hardware/rf-simulations/sim_wg_alumina_fast/port_it1B similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/port_it1B rename to hardware/rf-simulations/sim_wg_alumina_fast/port_it1B diff --git a/5_Simulations/sim_wg_alumina_fast/port_ut1A b/hardware/rf-simulations/sim_wg_alumina_fast/port_ut1A similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/port_ut1A rename to hardware/rf-simulations/sim_wg_alumina_fast/port_ut1A diff --git a/5_Simulations/sim_wg_alumina_fast/port_ut1B b/hardware/rf-simulations/sim_wg_alumina_fast/port_ut1B similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/port_ut1B rename to hardware/rf-simulations/sim_wg_alumina_fast/port_ut1B diff --git a/5_Simulations/sim_wg_alumina_fast/port_ut1C b/hardware/rf-simulations/sim_wg_alumina_fast/port_ut1C similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/port_ut1C rename to hardware/rf-simulations/sim_wg_alumina_fast/port_ut1C diff --git a/5_Simulations/sim_wg_alumina_fast/wg_alumina.xml b/hardware/rf-simulations/sim_wg_alumina_fast/wg_alumina.xml similarity index 100% rename from 5_Simulations/sim_wg_alumina_fast/wg_alumina.xml rename to hardware/rf-simulations/sim_wg_alumina_fast/wg_alumina.xml diff --git a/5_Simulations/slot_layout_taper32.csv b/hardware/rf-simulations/slot_layout_taper32.csv similarity index 100% rename from 5_Simulations/slot_layout_taper32.csv rename to hardware/rf-simulations/slot_layout_taper32.csv diff --git a/5_Simulations/wg_alumina_slotted_openems.m b/hardware/rf-simulations/wg_alumina_slotted_openems.m similarity index 100% rename from 5_Simulations/wg_alumina_slotted_openems.m rename to hardware/rf-simulations/wg_alumina_slotted_openems.m diff --git a/montecarlo_stats.json b/montecarlo_stats.json deleted file mode 100644 index fbcc6de..0000000 --- a/montecarlo_stats.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "shahed-136": { - "total_trials": 100, - "collisions": 100, - "interception_rate": 100.0, - "avg_detection_time": 6.96, - "avg_collision_time": 88.525, - "avg_impact_time": null, - "avg_observations": 165.13 - }, - "shahed-238": { - "total_trials": 100, - "collisions": 68, - "interception_rate": 68.0, - "avg_detection_time": 27.205, - "avg_collision_time": 85.77941176470588, - "avg_impact_time": 169.984375, - "avg_observations": 173.36 - }, - "cruise-missile": { - "total_trials": 100, - "collisions": 36, - "interception_rate": 36.0, - "avg_detection_time": 64.655, - "avg_collision_time": 98.88888888888889, - "avg_impact_time": 137.6015625, - "avg_observations": 120.66 - }, - "ballistic-reentry": { - "total_trials": 100, - "collisions": 0, - "interception_rate": 0.0, - "avg_detection_time": 110.91304347826087, - "avg_collision_time": null, - "avg_impact_time": 114.615, - "avg_observations": 7.54 - }, - "prop-drone": { - "total_trials": 100, - "collisions": 100, - "interception_rate": 100.0, - "avg_detection_time": 1.0, - "avg_collision_time": 44.19, - "avg_impact_time": null, - "avg_observations": 88.38 - } -} \ No newline at end of file diff --git a/parts/README.md b/parts/README.md new file mode 100644 index 0000000..956b644 --- /dev/null +++ b/parts/README.md @@ -0,0 +1,13 @@ +# Parts list + +`parts-list.csv` is the five production bills of materials in one table: + +- Main board +- Power board +- Frequency synthesizer +- Power amplifier, one board +- Patch antenna + +Quantities are **per board**. The extended radar uses 16 power-amplifier boards. On the main board the Eagle export left `value` blank and put the part name in `device`; both columns are kept. The original spreadsheets remain next to the Gerbers under `schematics/4_7_Production Files/`. Datasheets are in `datasheets/`. + +The power-rail sheet in `hardware/power/` is a current and sequencing budget, not a price list. diff --git a/parts/cost.md b/parts/cost.md new file mode 100644 index 0000000..93822f2 --- /dev/null +++ b/parts/cost.md @@ -0,0 +1,9 @@ +# Cost + +There is no cost estimate in this repository. + +Every production bill of materials lists quantity, value, and a manufacturer part number. None of them has a unit price or a currency column, so a total cannot be added up from the files that are here. + +The only price comment is a note on the main-board mixer `LTC5552IUDB#TRMPBF` (U5, U13): the price was rising, and the price to use is the one at order time. No figure is written down. + +`parts-list.csv` is the list those prices would attach to. diff --git a/7_Components Datasheets and Application notes/60124102122403.pdf b/parts/datasheets/60124102122403.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/60124102122403.pdf rename to parts/datasheets/60124102122403.pdf diff --git a/7_Components Datasheets and Application notes/8-12GHz MTH801C-20 SMA Broadband Circulator .pdf b/parts/datasheets/8-12GHz MTH801C-20 SMA Broadband Circulator .pdf similarity index 100% rename from 7_Components Datasheets and Application notes/8-12GHz MTH801C-20 SMA Broadband Circulator .pdf rename to parts/datasheets/8-12GHz MTH801C-20 SMA Broadband Circulator .pdf diff --git a/7_Components Datasheets and Application notes/AD9484/AD9434_AD9484_Schematic.pdf b/parts/datasheets/AD9484/AD9434_AD9484_Schematic.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AD9484/AD9434_AD9484_Schematic.pdf rename to parts/datasheets/AD9484/AD9434_AD9484_Schematic.pdf diff --git a/7_Components Datasheets and Application notes/AD9484/AD9484.pdf b/parts/datasheets/AD9484/AD9484.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AD9484/AD9484.pdf rename to parts/datasheets/AD9484/AD9484.pdf diff --git a/7_Components Datasheets and Application notes/AD9484/RX_Chain_Gain_Noise_Summary_ABAC_Radar.docx b/parts/datasheets/AD9484/RX_Chain_Gain_Noise_Summary_ABAC_Radar.docx similarity index 100% rename from 7_Components Datasheets and Application notes/AD9484/RX_Chain_Gain_Noise_Summary_ABAC_Radar.docx rename to parts/datasheets/AD9484/RX_Chain_Gain_Noise_Summary_ABAC_Radar.docx diff --git a/7_Components Datasheets and Application notes/AD9484/UG-290.pdf b/parts/datasheets/AD9484/UG-290.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AD9484/UG-290.pdf rename to parts/datasheets/AD9484/UG-290.pdf diff --git a/7_Components Datasheets and Application notes/AD9484/ad8352.pdf b/parts/datasheets/AD9484/ad8352.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AD9484/ad8352.pdf rename to parts/datasheets/AD9484/ad8352.pdf diff --git a/7_Components Datasheets and Application notes/AD9708.pdf b/parts/datasheets/AD9708.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AD9708.pdf rename to parts/datasheets/AD9708.pdf diff --git a/7_Components Datasheets and Application notes/ADAR1000.pdf b/parts/datasheets/ADAR1000.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ADAR1000.pdf rename to parts/datasheets/ADAR1000.pdf diff --git a/7_Components Datasheets and Application notes/ADF4382A/ADF4382A.pdf b/parts/datasheets/ADF4382A/ADF4382A.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ADF4382A/ADF4382A.pdf rename to parts/datasheets/ADF4382A/ADF4382A.pdf diff --git a/7_Components Datasheets and Application notes/ADF4382A/eval_adf4382a_ug_2185-3392420.pdf b/parts/datasheets/ADF4382A/eval_adf4382a_ug_2185-3392420.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ADF4382A/eval_adf4382a_ug_2185-3392420.pdf rename to parts/datasheets/ADF4382A/eval_adf4382a_ug_2185-3392420.pdf diff --git a/7_Components Datasheets and Application notes/ADM7151.pdf b/parts/datasheets/ADM7151.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ADM7151.pdf rename to parts/datasheets/ADM7151.pdf diff --git a/7_Components Datasheets and Application notes/AT93C46A.pdf b/parts/datasheets/AT93C46A.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/AT93C46A.pdf rename to parts/datasheets/AT93C46A.pdf diff --git a/7_Components Datasheets and Application notes/DS_FT2232H.pdf b/parts/datasheets/DS_FT2232H.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/DS_FT2232H.pdf rename to parts/datasheets/DS_FT2232H.pdf diff --git a/7_Components Datasheets and Application notes/DS_FT232RN.pdf b/parts/datasheets/DS_FT232RN.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/DS_FT232RN.pdf rename to parts/datasheets/DS_FT232RN.pdf diff --git a/7_Components Datasheets and Application notes/EP4RKU_2b-1858448.pdf b/parts/datasheets/EP4RKU_2b-1858448.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/EP4RKU_2b-1858448.pdf rename to parts/datasheets/EP4RKU_2b-1858448.pdf diff --git a/7_Components Datasheets and Application notes/FR2-SMA-KFD0405A_2025-08-11.pdf b/parts/datasheets/FR2-SMA-KFD0405A_2025-08-11.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/FR2-SMA-KFD0405A_2025-08-11.pdf rename to parts/datasheets/FR2-SMA-KFD0405A_2025-08-11.pdf diff --git a/7_Components Datasheets and Application notes/LTC5552f.pdf b/parts/datasheets/LTC5552f.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/LTC5552f.pdf rename to parts/datasheets/LTC5552f.pdf diff --git a/7_Components Datasheets and Application notes/LTC6419fa.pdf b/parts/datasheets/LTC6419fa.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/LTC6419fa.pdf rename to parts/datasheets/LTC6419fa.pdf diff --git a/7_Components Datasheets and Application notes/M3SWA2-34DR+.pdf b/parts/datasheets/M3SWA2-34DR+.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/M3SWA2-34DR+.pdf rename to parts/datasheets/M3SWA2-34DR+.pdf diff --git a/7_Components Datasheets and Application notes/MAX1449-3468915.pdf b/parts/datasheets/MAX1449-3468915.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/MAX1449-3468915.pdf rename to parts/datasheets/MAX1449-3468915.pdf diff --git a/7_Components Datasheets and Application notes/MMIQA-0218HPSM-Integrated Drive GaAs MMIC IQ Mixer.pdf b/parts/datasheets/MMIQA-0218HPSM-Integrated Drive GaAs MMIC IQ Mixer.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/MMIQA-0218HPSM-Integrated Drive GaAs MMIC IQ Mixer.pdf rename to parts/datasheets/MMIQA-0218HPSM-Integrated Drive GaAs MMIC IQ Mixer.pdf diff --git a/7_Components Datasheets and Application notes/MTX2-143+.pdf b/parts/datasheets/MTX2-143+.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/MTX2-143+.pdf rename to parts/datasheets/MTX2-143+.pdf diff --git a/7_Components Datasheets and Application notes/PMA2-123LNW+.pdf b/parts/datasheets/PMA2-123LNW+.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/PMA2-123LNW+.pdf rename to parts/datasheets/PMA2-123LNW+.pdf diff --git a/7_Components Datasheets and Application notes/PMA5_123_3W_2b-3577903.pdf b/parts/datasheets/PMA5_123_3W_2b-3577903.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/PMA5_123_3W_2b-3577903.pdf rename to parts/datasheets/PMA5_123_3W_2b-3577903.pdf diff --git a/7_Components Datasheets and Application notes/QPA1013D Data Sheet.pdf b/parts/datasheets/QPA1013D Data Sheet.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/QPA1013D Data Sheet.pdf rename to parts/datasheets/QPA1013D Data Sheet.pdf diff --git a/7_Components Datasheets and Application notes/QPA2962/QPA2962 Data Sheet.pdf b/parts/datasheets/QPA2962/QPA2962 Data Sheet.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/QPA2962/QPA2962 Data Sheet.pdf rename to parts/datasheets/QPA2962/QPA2962 Data Sheet.pdf diff --git a/7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_25C.s2p b/parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_25C.s2p similarity index 100% rename from 7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_25C.s2p rename to parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_25C.s2p diff --git a/7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_85C.s2p b/parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_85C.s2p similarity index 100% rename from 7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_85C.s2p rename to parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_85C.s2p diff --git a/7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_n40C.s2p b/parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_n40C.s2p similarity index 100% rename from 7_Components Datasheets and Application notes/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_n40C.s2p rename to parts/datasheets/QPA2962/QPA2962_22V1680mA_s2p/QPA2962_SN63_22v1680ma_n40C.s2p diff --git a/7_Components Datasheets and Application notes/QPM1021 Data Sheet.pdf b/parts/datasheets/QPM1021 Data Sheet.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/QPM1021 Data Sheet.pdf rename to parts/datasheets/QPM1021 Data Sheet.pdf diff --git a/7_Components Datasheets and Application notes/RO4000 Laminates RO4003C and RO4350B - Data Sheet (1).pdf b/parts/datasheets/RO4000 Laminates RO4003C and RO4350B - Data Sheet (1).pdf similarity index 100% rename from 7_Components Datasheets and Application notes/RO4000 Laminates RO4003C and RO4350B - Data Sheet (1).pdf rename to parts/datasheets/RO4000 Laminates RO4003C and RO4350B - Data Sheet (1).pdf diff --git a/7_Components Datasheets and Application notes/RO4000 Laminates RO4003C and RO4350B - Data Sheet.pdf b/parts/datasheets/RO4000 Laminates RO4003C and RO4350B - Data Sheet.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/RO4000 Laminates RO4003C and RO4350B - Data Sheet.pdf rename to parts/datasheets/RO4000 Laminates RO4003C and RO4350B - Data Sheet.pdf diff --git a/7_Components Datasheets and Application notes/SMIQ-5143H+.pdf b/parts/datasheets/SMIQ-5143H+.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/SMIQ-5143H+.pdf rename to parts/datasheets/SMIQ-5143H+.pdf diff --git a/7_Components Datasheets and Application notes/STUW81300TR.pdf b/parts/datasheets/STUW81300TR.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/STUW81300TR.pdf rename to parts/datasheets/STUW81300TR.pdf diff --git a/7_Components Datasheets and Application notes/TGA2623_Data_Sheet-1518452.pdf b/parts/datasheets/TGA2623_Data_Sheet-1518452.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/TGA2623_Data_Sheet-1518452.pdf rename to parts/datasheets/TGA2623_Data_Sheet-1518452.pdf diff --git a/7_Components Datasheets and Application notes/ads7830.pdf b/parts/datasheets/ads7830.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ads7830.pdf rename to parts/datasheets/ads7830.pdf diff --git a/7_Components Datasheets and Application notes/adtr1107.pdf b/parts/datasheets/adtr1107.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/adtr1107.pdf rename to parts/datasheets/adtr1107.pdf diff --git a/7_Components Datasheets and Application notes/attenuator_n_catalog_partition37_en.pdf b/parts/datasheets/attenuator_n_catalog_partition37_en.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/attenuator_n_catalog_partition37_en.pdf rename to parts/datasheets/attenuator_n_catalog_partition37_en.pdf diff --git a/7_Components Datasheets and Application notes/dac7578.pdf b/parts/datasheets/dac7578.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/dac7578.pdf rename to parts/datasheets/dac7578.pdf diff --git a/7_Components Datasheets and Application notes/hr2220p601r-10-datasheet.pdf b/parts/datasheets/hr2220p601r-10-datasheet.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/hr2220p601r-10-datasheet.pdf rename to parts/datasheets/hr2220p601r-10-datasheet.pdf diff --git a/7_Components Datasheets and Application notes/ina241a.pdf b/parts/datasheets/ina241a.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/ina241a.pdf rename to parts/datasheets/ina241a.pdf diff --git a/7_Components Datasheets and Application notes/lm2663.pdf b/parts/datasheets/lm2663.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/lm2663.pdf rename to parts/datasheets/lm2663.pdf diff --git a/7_Components Datasheets and Application notes/max20029-max20029d.pdf b/parts/datasheets/max20029-max20029d.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/max20029-max20029d.pdf rename to parts/datasheets/max20029-max20029d.pdf diff --git a/7_Components Datasheets and Application notes/opa703.pdf b/parts/datasheets/opa703.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/opa703.pdf rename to parts/datasheets/opa703.pdf diff --git a/7_Components Datasheets and Application notes/tmp35_36_37.pdf b/parts/datasheets/tmp35_36_37.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/tmp35_36_37.pdf rename to parts/datasheets/tmp35_36_37.pdf diff --git a/7_Components Datasheets and Application notes/tps562201.pdf b/parts/datasheets/tps562201.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/tps562201.pdf rename to parts/datasheets/tps562201.pdf diff --git a/7_Components Datasheets and Application notes/tps7a8300.pdf b/parts/datasheets/tps7a8300.pdf similarity index 100% rename from 7_Components Datasheets and Application notes/tps7a8300.pdf rename to parts/datasheets/tps7a8300.pdf diff --git a/parts/parts-list.csv b/parts/parts-list.csv new file mode 100644 index 0000000..e924146 --- /dev/null +++ b/parts/parts-list.csv @@ -0,0 +1,183 @@ +board,qty_per_board,value,device,manufacturer_part_number,description,designators,source +Main board,11,,L-EUL5650M,HI2220P601R-10,"INDUCTOR, European symbol","L1, L11, L12, L13, L14, L15, L16, L17, L18, L21, L23",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,MA10-2,MA10-2,PIN HEADER,SV1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-1X2,Do Not Put,PIN HEADER,JP20,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,11,,PINHD-1X3,Do Not Put,PIN HEADER,"JP4, JP5, JP6, JP10, JP11, JP12, JP14, JP15, JP16, JP17, JP19",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,,PINHD-1X4,Do Not Put,PIN HEADER,"JP8, JP9, JP18",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-1X6,Do Not Put,PIN HEADER,JP2,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-1X8,Do Not Put,PIN HEADER,JP7,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-2X4,Do Not Put,PIN HEADER,JP3,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-2X6,87834-1211,PIN HEADER,JP1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,PINHD-2X7,90130-1314,PIN HEADER,JP13,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,,SJ2W,Do Not Put,SMD solder JUMPER,SJ1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,75,0.1uF,CC0201,CL03A104KP3NNNH,"CAPACITOR, European symbol","C1, C2, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C36, C37, C38, C39, C40, C41, C42, C44, C45, C46, C47, C51, C52, C53, C56, C67, C69, C74, C80, C82, C125, C131, C133, C138, C140, C146, C148, C159, C160, C162, C168, C170, C175, C188, C189, C190, C192, C193, C194, C195, C196, C201, C203, C208, C210, C215, C217, C222, C224, C229, C231, C236, C238, C243, C245, C250, C252, C293",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,0.1uF,C-EUC0402,GRM155R71C104KA88D,"CAPACITOR, European symbol","C48, C49, C57, C58",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,6,0.1uF,CC0201,CL03A104KP3NNNH,"CAPACITOR, European symbol","C277, C278, C295, C297, C299, C301, C352, C352",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,0.2pF,C-EUC0201,GJM0335C1ER20WB01D,"CAPACITOR, European symbol",C43,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,13,0.47uF,CC0201,CL03A474KP3NNNC,"CAPACITOR, European symbol","C110, C111, C112, C113, C155, C156, C157, C158, C179, C180, C181, C182, C291",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,0.6pF,C-EUC0201,GJM0335C1ER60WB01D,"CAPACITOR, European symbol",C54,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,0R,RR0201,RCA02010000ZSEDSR,"RESISTOR, European symbol","R18, R19, R34, R35",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,12,100R,RR0201,RC0201FR-07100RL,"RESISTOR, European symbol","R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R173",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,28,100nF,C-EUC0402,GRM155R71C104KA88D,"CAPACITOR, European symbol","C76, C78, C258, C259, C260, C262, C264, C266, C313, C317, C320, C324, C327, C331, C334, C337, C339, C341, C342, C343, C344, C345, C346, C347, C348, C349, C350, C351",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,24,100nF,CC0201,CL03A104KP3NNNH,"CAPACITOR, European symbol","C24, C25, C26, C27, C28, C29, C30, C32, C33, C34, C35, C50, C256, C257, C279, C281, C298, C302, C303, C304, C305, C306, C307, C310",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,34,100pF,CC0201,0201CG101J500NT,"CAPACITOR, European symbol","C66, C68, C73, C79, C81, C124, C130, C132, C137, C139, C145, C147, C152, C161, C167, C169, C174, C183, C200, C202, C207, C209, C214, C216, C221, C223, C228, C230, C235, C237, C242, C244, C249, C251",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,103pF,CC0201,MLASU063SCG101JFNA01,"CAPACITOR, European symbol","C60, C63",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,106pF,CC0201,GRM0335C1H111GA01D,"CAPACITOR, European symbol",C141,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,107.3nH,LL0201,MLG0603PR11JTD25,"INDUCTOR, European symbol","L22, L25, L26, L27",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,9,10k,RR0201,AC0201FR-0710KL,"RESISTOR, European symbol","R39, R40, R83, R84, R111, R123, R145, R151, R153",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,10nF,CC0201,0201B103K250NT,"CAPACITOR, European symbol","C102, C103, C104, C105, C106, C107, C114, C115, C116, C117, C118, C119, C120, C121, C122, C123",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,12,10uF,C-EUC0805,GRM21BR61E106KA73L,"CAPACITOR, European symbol","C75, C77, C312, C316, C319, C323, C326, C330, C333, C336, C338, C340",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,115R,R-EU_R0201,RC0201FR-07115RL,"RESISTOR, European symbol",R14,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,12nH,LL0201,LQP02TN12NH02D,"INDUCTOR, European symbol","L2, L8",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,12pF,CC0201,GRM0335C1E120JA01D,"CAPACITOR, European symbol","C184, C185",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,37,142-0731-211,142-0731-211,142-0731-211,"SMA Connector Jack, Female Socket 50 Ohms Through Hole Solder","J1, J18, J20, J22, J23, J24, J25, J26, J27, J28, J29, J30, J31, J32, J33, J34, J35, J36, J37, J38, J39, J40, J41, J42, J43, J44, J45, J46, J47, J48, J49, J50, J51, J52, J53, J54, J55",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,159nH,LL0201,LQP03TNR16H02D,"INDUCTOR, European symbol","L3, L4",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,18pF,CC0201,GRM0335C1E180JA01D,"CAPACITOR, European symbol","C272, C274",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,1k,R-EU_R0402,RC0402FR-071KL,"RESISTOR, European symbol",R37,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,49,1k,RR0201,1-2176072-2,"RESISTOR, European symbol","R41, R43, R55, R56, R57, R58, R59, R61, R82, R85, R86, R87, R88, R93, R94, R99, R100, R101, R102, R107, R108, R109, R118, R124, R125, R126, R127, R128, R129, R130, R131, R133, R134, R135, R136, R137, R138, R139, R140, R144, R147, R148, R149, R167, R168, R169, R170, R171, R172",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,1k2_1%,RR0201,RC0201FR-071K2L,"RESISTOR, European symbol",R60,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,7,1nF,C-EUC0402,CL03B102KA3NNNC,"CAPACITOR, European symbol","C314, C318, C321, C325, C328, C332, C335",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,51,1pF,CC0201,GJM0335C1E1R0WB01D,"CAPACITOR, European symbol","C70, C71, C72, C83, C84, C85, C126, C128, C129, C134, C135, C136, C142, C143, C144, C149, C150, C151, C163, C165, C166, C171, C172, C173, C197, C198, C199, C204, C205, C206, C211, C212, C213, C218, C219, C220, C225, C226, C227, C232, C233, C234, C239, C240, C241, C246, C247, C248, C253, C254, C255",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,1uF,CC0201,CL03A105MQ3CSNH,"CAPACITOR, European symbol","C86, C87, C88, C89, C90, C91, C92, C93, C94, C95, C96, C97, C98, C99, C100, C101",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,1uF,CC0201,CL03A105MQ3CSNH,"CAPACITOR, European symbol","C276, C296, C300",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,2.2k,RR0201,RC0201FR-072K2L,"RESISTOR, European symbol",R146,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,2.2uF,CC0201,GRM033R60J225ME47D,"CAPACITOR, European symbol","C22, C23, C164",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,2.443k,RR0201,RC0201FR-072K44L,"RESISTOR, European symbol","R89, R90, R91, R92, R95, R96, R97, R98, R103, R104, R105, R106, R119, R120, R121, R122",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,2.7pF,C-EUC0402,GJM1555C1H2R7WB01D,"CAPACITOR, European symbol",C3,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,20pF,CC0201,GCQ0335C1H200GB01D,"CAPACITOR, European symbol","C18, C19",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,200R,RR0201,RC0201FR-07200RL,"RESISTOR, European symbol","R16, R17, R20, R21",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,20k,R-EU_R0402,RC0402FR-0720KL,"RESISTOR, European symbol",R38,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,40,22-23-2021,22-23-2021,22-23-2021,".100 (2.54mm) Center Header - 2 Pin""","X1, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X24, X54, X55, X56, X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8, X_9, X_10, X_11, X_12, X_13, X_14, X_15, X_16",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,22-23-2031,22-23-2031,22-23-2031,".100 (2.54mm) Center Header - 3 Pin""","X3, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,11,22.1k,RR0201,RC0201FR-0722K1L,"RESISTOR, European symbol","R154, R155, R156, R157, R158, R159, R160, R161, R162, R163, R164",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,13,22R,RR0201,RC0201FR-0722RL,"RESISTOR, European symbol","R23, R24, R25, R26, R27, R28, R29, R30, R49, R51, R62, R63, R64",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,22pF,CC0201,GRM0335C1E220JA01D,"CAPACITOR, European symbol","C308, C309",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,5,22uF,C-EUC1206,GRM31CR61E226ME15L,"CAPACITOR, European symbol","C283, C311, C315, C322, C329",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,24R,R-EU_R0402,RC0402FR-0724RL,"RESISTOR, European symbol","R1, R13",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,25R,RR0201,RC0201FR-0725RL,"RESISTOR, European symbol","R165, R166",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,25pF,CC0201,GRM0335C1E250JA01D,"CAPACITOR, European symbol","C64, C65, C268, C270",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,3.3uF,CC0201,GRM033R60J335ME47D,"CAPACITOR, European symbol",C191,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,32.8pF,CC0201,GJM0335C1E330JB01D,"CAPACITOR, European symbol","C59, C127",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,3k2,RR0201,RC0201FR-073K2L,"RESISTOR, European symbol",R33,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,4.3k,R-EU_R0201,RC0201FR-074K3L,"RESISTOR, European symbol","R15, R32",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,4.3pF,CC0201,GJM0335C1E4R3WB01D,"CAPACITOR, European symbol","C20, C21",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,27,4.7k,RR0201,RC0201FR-074K7L,"RESISTOR, European symbol","R42, R44, R45, R46, R47, R48, R50, R52, R53, R54, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, R77, R117, R141, R142, R143",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,4.7nF,CC0201,GRM033R71E472KA88D,"CAPACITOR, European symbol","C261, C263, C265, C267, C269, C271, C273, C275, C280, C282, C284, C286, C288, C290, C292, C294",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,8,4.7uF,CC0201,GRM033R60J475ME47D,"CAPACITOR, European symbol","C108, C109, C153, C154, C177, C178, C287, C289",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,4.7uF 35V,4.7UF-POLAR-EIA3528-35V-10%(TANT),595D475X9035B2T,,"C186, C187",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,47nF,CC0201,GRM033R71E473KA88D,"CAPACITOR, European symbol",C31,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,4.7uF,CC0201,CM03X5R475M06AH055,"CAPACITOR, European symbol","C17, C55, C176, C285",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,500R,RR0201,RC0201FR-07500RL,"RESISTOR, European symbol","R110, R112, R113, R114",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,50R,RR0201,RC0201FR-0750RL,"RESISTOR, European symbol","R31, R115, R116",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,50nH,LL0201,CE0603M-51NH,"INDUCTOR, European symbol","L9, L10, L24, L28",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,56R,R-EU_R0201,RC0201FR-0756RL,"RESISTOR, European symbol",R22,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,5R,RR0201,RC0201FR-075R1L,"RESISTOR, European symbol","R132, R150, R152",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,7.8pF,CC0201,GJM0335C1E7R8WB01D,"CAPACITOR, European symbol","C61, C62",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,830R,R-EU_R0402,RC0402FR-07830RL,"RESISTOR, European symbol",R36,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,840R,RR0201,RC0201FR-07840RL,"RESISTOR, European symbol","R78, R79, R80, R81",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,AD8352ACPZ-R7,AD8352ACPZ-R7,AD8352ACPZ-R7,,"U4, U8",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,AD9484BCPZ-500,AD9484BCPZ-500,AD9484BCPZ-500,,U1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,AD9708AR,AD9708AR,AD9708AR,,U3,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,ADAR1000ACCZN,ADAR1000ACCZN,ADAR1000ACCZN,,"ADAR1_, ADAR2_, ADAR3_, ADAR4_",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,3,ADS7830IPWR,ADS7830IPWR,ADS7830IPWR,,"U10, U88, U89",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,ADTR1107ACCZ,ADTR1107ACCZ,ADTR1107ACCZ,,"ADTR1107_1, ADTR1107_2, ADTR1107_3, ADTR1107_4, ADTR1107_5, ADTR1107_6, ADTR1107_7, ADTR1107_8, ADTR1107_9, ADTR1107_10, ADTR1107_11, ADTR1107_12, ADTR1107_13, ADTR1107_14, ADTR1107_15, ADTR1107_16",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,AT93C46A-10SQ-2.7,AT93C46A-10SQ-2.7,AT93C46A-10SQ-2.7,Three-wire Automotive Temperature Serial EEPROM 1K (64 x 16),IC1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,5,BLM15HB121SN1,BLM15HB121SN1,BLM15PE121SH1D,EMIFIL (R) Chip Ferrite Bead for GHz Noise,"L5, L6, L7, L19, L20",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,BPF2,BPF2,Not a component,,"U$2, U$3",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,Blue,LED-BLUE0603,KB EELP41.12-P1R2-36-3X4X-5-R18,Blue SMD LED,"D2, D3, D4, D5",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,CJT-T-P-HH-ST-TH1,CJT-T-P-HH-ST-TH1,CJT-T-P-HH-ST-TH1,Conn Twinax F 0Hz to 4GHz 100Ohm Solder ST Thru-Hole Gold,"J19, J21",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,DAC5578SRGET,DAC5578SRGET,DAC5578SRGET,,"U7, U69",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,ECS-120-10-36B2-JTN-TR,CRYSTAL-12MHZ,ECS-120-10-36B2-JTN-TR,12.0MHz Crystal,Y1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,EP4RKU+,EP4RKU+,EP4RKU+,,U16,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,FT2232HQ,FT2232HQ,FT2232HQ,,U6,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,16,INA241A3IDGKRDGK0008A-MFG,INA241A3IDGKRDGK0008A-MFG,INA241A3IDGKR,,"U11, U73, U74, U75, U76, U77, U78, U79, U80, U81, U82, U83, U84, U85, U86, U87",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,LTC5552IUDBTRMPBF,LTC5552IUDBTRMPBF,LTC5552IUDB#TRMPBF,,"U5, U13",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,17,M3SWA2-34DR+,M3SWA2-34DR+,M3SWA2-34DR+,,"RF_SW_1, RF_SW_2, RF_SW_3, RF_SW_4, RF_SW_5, RF_SW_6, RF_SW_7, RF_SW_8, RF_SW_9, RF_SW_10, RF_SW_11, RF_SW_12, RF_SW_13, RF_SW_14, RF_SW_15, RF_SW_16, U$1",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,2,MINI-USB-32005-201,MINI-USB-32005-201,10118192-0002LF,MINI USB-B Conector,"X2, X53",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,MOMENTARY-SWITCH-SPST-SMD-4.6X2.8MM,MOMENTARY-SWITCH-SPST-SMD-4.6X2.8MM,EVQP0E07K,Momentary Switch (Pushbutton) - SPST,S1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,MT25QL01GBBB8E12-0AUT,MT25QL01GBBB8E12-0AUT,MT25QL01GBBB8E12-0AUT,,U9,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,NX3215SA-32.768KHz,NX3225GD-8MHZ-STD-CRA-3,NX3215SA-32.768K-STD-MUS-2,,XTAL3,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,NX3225GD-8MHZ-STD-CRA-3,NX3225GD-8MHZ-STD-CRA-3,NX3225GD-8MHZ-STD-CRA-3,,XTAL1,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,4,OPA4703EA/250,OPA4703EA/250,OPA4703EA/250,,"OPA_1, OPA_2, OPA_3, OPA_4",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,STM32F746ZGT7,STM32F746ZGT7,STM32F746ZGT7,,U2,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,34,SZMMSZ5232BT1G,SZMMSZ5232BT1G,SZMMSZ5232BT1G,,"U14, U15, U17, U37, U38, U39, U40, U41, U43, U44, U45, U46, U47, U48, U49, U50, U51, U52, U53, U54, U55, U56, U57, U58, U59, U60, U61, U62, U63, U64, U65, U66, U67, U68",schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Main board,1,XC7A50T-2FTG256I,XC7A50T-2FTG256I,XC7A50T-2FTG256I,Artix-7 Field Programmable Gate Array (FPGA) IC 170 2764800 52160 256-LBGA Check availability,U42,schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx +Power board,1,,AK300/2,AK300/2,CONNECTOR,X1,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,,MA10-2,MA10-2,PIN HEADER,SV1,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,21,0.1µF,C-EUC0805,GCM21BR71E104JA37L,"CAPACITOR, European symbol","C1, C6, C12, C18, C29, C30, C36, C42, C54, C60, C66, C71, C76, C77, C83, C89, C109, C119, C129, C144, C154",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,27,10k,R-EU_M0805,AE0805BR-0710KL,"RESISTOR, European symbol","R2, R4, R6, R8, R10, R12, R14, R16, R18, R20, R22, R24, R26, R28, R30, R32, R34, R36, R38, R40, R42, R44, R46, R48, R50, R52, R56",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,4,10nF,C-EUC0603,06035D103JAT2A,"CAPACITOR, European symbol","C150, C152, C160, C162",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,4,10µF,C-EUC0603,ZRB18AR6YA106ME01L,"CAPACITOR, European symbol","C151, C153, C161, C163",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,60,10µF,C-EUC0805,CC0805KFX5R8BB106,"CAPACITOR, European symbol","C4, C5, C9, C10, C15, C16, C21, C22, C24, C25, C28, C33, C34, C39, C40, C45, C46, C50, C51, C52, C53, C57, C58, C63, C64, C69, C70, C74, C75, C80, C81, C86, C87, C92, C93, C94, C95, C108, C112, C113, C114, C115, C118, C122, C123, C124, C125, C128, C132, C133, C134, C135, C138, C139, C140, C143, C147, C148, C157, C158",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,2,11.5k,R-EU_M0805,CRCW080511K5FKTA,"RESISTOR, European symbol","R54, R58",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,4,12k,R-EU_M0805,KTR10EZPF1202,"RESISTOR, European symbol","R9, R35, R43, R47",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,13.7k,R-EU_M0805,ESR10EZPF1372,"RESISTOR, European symbol",R3,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,12,1µF,C-EUC0805,MSAYG21GSLD105KTNA01,"CAPACITOR, European symbol","C26, C27, C106, C107, C116, C117, C126, C127, C136, C137, C141, C142",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,2,2.2µH,POWER_INDUCTOR,DEM8045Z-2R2N=P3,,"U$1, U$2",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,35,22-23-2021,22-23-2021,22-23-2021,".100 (2.54mm) Center Header - 2 Pin""","X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,52,22µF,C-EUC0603,KGM15CR51E226MT,"CAPACITOR, European symbol","C2, C3, C7, C8, C11, C13, C14, C17, C19, C20, C23, C31, C32, C35, C37, C38, C41, C43, C44, C47, C48, C49, C55, C56, C59, C61, C62, C65, C67, C68, C72, C73, C78, C79, C82, C84, C85, C88, C90, C91, C110, C111, C120, C121, C130, C131, C145, C146, C149, C155, C156, C159",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,23.4k,R-EU_M0805,RK73H2ATTD2372F,"RESISTOR, European symbol",R49,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,2k,R-EU_M0805,ERJ-P06D2001V,"RESISTOR, European symbol",R39,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,3.09k,R-EU_M0805,ERJ-P06F3091V,"RESISTOR, European symbol",R1,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,19,3.3µH,POWER_INDUCTOR,DEM8045Z-3R3N=P3,,"U$3, U$4, U$5, U$6, U$7, U$8, U$9, U$10, U$11, U$12, U$13, U$14, U$15, U$16, U$17, U$18, U$19, U$20, U$21",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,6,32.2k,R-EU_M0805,CRCW080532K4FKEAHP,"RESISTOR, European symbol","R5, R7, R11, R13, R15, R19",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,34.8k,R-EU_M0805,ERJ-P06F3482V,"RESISTOR, European symbol",R21,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,2,35.7k,R-EU_M0805,ERJ-P06F3572V,"RESISTOR, European symbol","R53, R57",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,11,56.2k,R-EU_M0805,CRCW080556K2FKEAHP,"RESISTOR, European symbol","R17, R23, R25, R27, R29, R31, R37, R41, R45, R51, R55",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,1,61.9k,R-EU_M0805,CRCW080561K9FKEA,"RESISTOR, European symbol",R33,schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,6,ADM7151ACPZ-04-R7,ADM7151ACPZ-04-R7,ADM7151ACPZ-04-R7,,"U5, U23, U25, U27, U29, U30",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,5,LM2662MX/NOPB,LM2662MX/NOPB,LM2662MX/NOPB,,"U18, U19, U20, U21, U22",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,10,T521W476M020ATE045,T521W476M020ATE045,T521W476M020ATE045,"T521, Tantalum, Polymer Tantalum, Commercial Grade, 47 uF, 20%, 20 VDC, 105C, -55C, 105C, SMD, Polymer, Molded, Low Profile/ESR, NonCombustible, 2,000 Hrs, 9 % , 45 mOhms, 94 uA, 222.95 mg, 7343, 1.4mm, Height Max = 1.5mm, 1000, 52 Weeks","C96, C97, C98, C99, C100, C101, C102, C103, C104, C105",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,21,TPS562208DDCT,TPS562208DDCT,TPS562208DDCT,,"U1, U2, U3, U4, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U24, U26, U28, U31, U33",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Power board,2,TPS7A8300RGRR,TPS7A8300RGRR,TPS7A8300RGRR,,"U32, U34",schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx +Frequency synthesizer,5,,L-EUL5650M,HI2220P601R-10,"INDUCTOR, European symbol","L9, L10, L11, L12, L13",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,,PINHD-2X6,87834-1211,PIN HEADER,JP1,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,,PINHD-2X7,90130-1314,PIN HEADER,JP2,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,28,0.1µF,C-EUC0201,CL03A104KP3NNNH,"CAPACITOR, European symbol","C16, C18, C20, C22, C24, C26, C28, C30, C32, C34, C35, C36, C37, C41, C42, C43, C44, C64, C65, C66, C67, C87, C88, C90, C91, C4, C5, C7",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,0.1µf,C-EUC0201,CL03A104KP3NNNH,"CAPACITOR, European symbol",C92,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,0.33µF,C-EUC0201,0201X334M6R3CT,"CAPACITOR, European symbol","C2, C6",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,0.47µF,C-EUC0201,CL03A474KP3NNNC,"CAPACITOR, European symbol","C9, C10",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,0.47µf,C-EUC0201,CL03A474KP3NNNC,"CAPACITOR, European symbol",C3,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,3,0.65k,R-EU_R0201,CPF0201B649RE1,"RESISTOR, European symbol","R6, R8, R10",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,9,0R,R-EU_R0201,RCA02010000ZSEDSR,"RESISTOR, European symbol","R5, R14, R15, R19, R20, R27, R28, R32, R33",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,8,1.3nH,L-USL0201,LQP03HQ1N3W02D,"INDUCTOR, American symbol","L1, L2, L3, L4, L5, L6, L7, L8",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,1000pF,C-EUC0201,CL03B102KA3NNNC,"CAPACITOR, European symbol",C8,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,4,100R,R-EU_R0201,RC0201FR-07100RL,"RESISTOR, European symbol","R1, R12, R13, R26",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,10nF,C-EUC0201,0201B103K250NT,"CAPACITOR, European symbol","C61, C84",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,3,10nF,C-EUC0402,GRM1555CYA103GE01J,"CAPACITOR, European symbol","C15, C17, C19",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,6,10pF,C-EUC0201,CL03C100JA3GNNC,"CAPACITOR, European symbol","C1, C62, C63, C85, C86, C89",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,5,10µF,C-EUC1210,MBASU32MAB7106KPNA01,"CAPACITOR, European symbol","C23, C27, C31, C45, C47",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,11,142-0731-211,142-0731-211,142-0731-211,"SMA Connector Jack, Female Socket 50 Ohms Through Hole Solder","J1, J2, J5, J6, J7, J8, J9, J10, J11, J12, J13",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,6,1k,R-EU_R0201,1-2176072-2,"RESISTOR, European symbol","R2, R3, R4, R7, R9, R11",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,10,1µF,C-EUC0201,CL03A105MQ3CSNH,"CAPACITOR, European symbol","C11, C12, C13, C14, C59, C68, C69, C70, C71, C82",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,8,200k,R-EU_R0201,RE0201BRE07200KL,"RESISTOR, European symbol","R22, R23, R24, R25, R35, R36, R37, R38",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,6,22-23-2021,22-23-2021,22-23-2021,".100 (2.54mm) Center Header - 2 Pin""","X10, X11, X12, X13, X14, X15",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,3,22R,R-EU_R0201,RT0201FRE0722RL,"RESISTOR, European symbol","R39, R40, R41",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,6,22µF,C-EUC1210,MAAST32MSB7226MPNA01,"CAPACITOR, European symbol","C21, C25, C29, C33, C46, C51",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,30R,R-EU_R0201,ERJ-U01J300C,"RESISTOR, European symbol","R17, R30",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,31pF,C-EUC0201,GCM0335C1H300FA16J,"CAPACITOR, European symbol","C60, C83",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,330R,R-EU_R0201,RC0201FR-7D330RL,"RESISTOR, European symbol","R18, R31",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,20,4.7µF,C-EUC0201,GRM035R60J475ME15D,"CAPACITOR, European symbol","C38, C39, C40, C48, C49, C50, C55, C56, C57, C58, C72, C73, C74, C75, C76, C77, C78, C79, C80, C81",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,500R,R-EU_R0201,CPF0201B499RE1,"RESISTOR, European symbol","R21, R34",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,931R,R-EU_R0201,CRCW0201931RFKED,"RESISTOR, European symbol","R16, R29",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,AD9523BCPZ,AD9523BCPZ,AD9523BCPZ,"AD9523BCPZ, PLL Clock Driver Dual, 72-Pin LFCSP VQ",IC1,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,ADF4382ABCCZ,ADF4382ABCCZ,ADF4382ABCCZ,,"U1, U6",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,4,ATS1005-3DB-FD-T05,ATS1005-3DB-FD-T05,ATS1005-3DB-FD-T05,,"U4, U5, U8, U10",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,CJT-T-P-HH-ST-TH1,CJT-T-P-HH-ST-TH1,CJT-T-P-HH-ST-TH1,,"J3, J4",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,CVHD-950-50.000,CVHD-950-50.000,CVHD-950-50.000,,"X5, X6",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,1,ECOC-2522-100.000-3HC,ECOC-2522-100.000-3HC,ECOC-2522-100.000-3HC,,X4,schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,4,FBMH1608HL601-T,FBMH1608HL601-T,FBMH1608HL601-T,,"FB1, FB2, FB3, FB4",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,2,Green,LED-GREEN-0603-WE,KB EELP41.12-P1R2-36-3X4X-5-R18,Green SMD LED,"D1, D2",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Frequency synthesizer,4,MTX2-143+,MTX2-143+,MTX2-143+,,"U2, U3, U7, U9",schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx +Power amplifier (one board),1,,AK300/2,AK300/2,CONNECTOR,22V,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),6,0.1µF,C-EUC0402,CL05B104KBD6PJC,"CAPACITOR, European symbol","C2, C3, C6, C7, C8, C9",schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),6,0R,R-EU_R0402,5113,"RESISTOR, European symbol","R2, R3, R5, R7, R8, R9",schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),1,0R,R-EU_R0603,RCA06030000ZSTA,"RESISTOR, European symbol",R6,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),2,10R,R-EU_R0402,RN73H1ETTP10R1F50,"RESISTOR, European symbol","R1, R4",schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),3,10µF,C-EUC1206,MLASU31LBB5106KTNA01,"CAPACITOR, European symbol","C1, C4, C5",schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),2,142-0731-211,142-0731-211,142-0731-211,"SMA Connector Jack, Female Socket 50 Ohms Through Hole Solder","J1, J2",schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),1,22-23-2021,22-23-2021,22-23-2021,".100 (2.54mm) Center Header - 2 Pin""",X2,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),1,22-23-2031,22-23-2031,22-23-2031,".100 (2.54mm) Center Header - 3 Pin""",X3,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),1,5mR,WSL2816R1000FEH,WSL2816R1000FEH,Shunt Resistor,R10,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Power amplifier (one board),1,QPA2962_B,QPA2962_B,QPA2962,RF Amplifier,U$1,schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx +Patch antenna,11,142-0731-211,142-0731-211,142-0731-211,"SMA Connector Jack, Female Socket 50 Ohms Through Hole Solder","J1, J2, J3, J4, J5, J6, J7, J8, J9, J10, J11, J12, J13, J14, J15, J17",schematics/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx diff --git a/run_simulation.sh b/run_simulation.sh deleted file mode 100755 index e14a51a..0000000 --- a/run_simulation.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# Run radar simulation with venv setup - -# Create venv if it doesn't exist -if [ ! -d "/tmp/radar_env" ]; then - echo "Creating virtual environment..." - python3 -m venv /tmp/radar_env -fi - -# Activate venv and install dependencies -source /tmp/radar_env/bin/activate -pip install numpy scipy matplotlib --quiet - -# Run the specified simulation -if [ -z "$1" ]; then - echo "Usage: $0 " - exit 1 -fi - -echo "Running $1..." -python3 "$1" diff --git a/4_Schematics and Boards Layout/4_4_Board Stack-up/Stack_Hybrid.png b/schematics/4_4_Board Stack-up/Stack_Hybrid.png similarity index 100% rename from 4_Schematics and Boards Layout/4_4_Board Stack-up/Stack_Hybrid.png rename to schematics/4_4_Board Stack-up/Stack_Hybrid.png diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.brd b/schematics/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.brd rename to schematics/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.sch b/schematics/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.sch rename to schematics/4_6_Schematics/Antennas/Patch/4x4/Phased_Array_Ant.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#1 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#1 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#1 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#1 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#2 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#2 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#2 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#2 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#3 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#3 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#3 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#3 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#4 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#4 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#4 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#4 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#5 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#5 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#5 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#5 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#6 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#6 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#6 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#6 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#7 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#7 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#7 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#7 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#8 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#8 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#8 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#8 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#9 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#9 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#9 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.b#9 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.brd b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.brd rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#1 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#1 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#1 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#1 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#2 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#2 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#2 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#2 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#3 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#3 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#3 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#3 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#4 b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#4 similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#4 rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.s#4 diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.sch b/schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.sch rename to schematics/4_6_Schematics/Antennas/Patch/8x16/Patch_Anetnna_16_8.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/place.scr b/schematics/4_6_Schematics/Antennas/Patch/8x16/place.scr similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Patch/8x16/place.scr rename to schematics/4_6_Schematics/Antennas/Patch/8x16/place.scr diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg b/schematics/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg rename to schematics/4_6_Schematics/Antennas/Waveguide/DFSWA.dwg diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/Dielectric_Filled_Waveguide_Array_Spec.docx b/schematics/4_6_Schematics/Antennas/Waveguide/Dielectric_Filled_Waveguide_Array_Spec.docx similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Antennas/Waveguide/Dielectric_Filled_Waveguide_Array_Spec.docx rename to schematics/4_6_Schematics/Antennas/Waveguide/Dielectric_Filled_Waveguide_Array_Spec.docx diff --git a/4_Schematics and Boards Layout/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.brd b/schematics/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.brd rename to schematics/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.sch b/schematics/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.sch rename to schematics/4_6_Schematics/FrequencySynthesizerBoard/Clocks_Freq_Synth_board.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/MainBoard/RADAR_Main_Board.brd b/schematics/4_6_Schematics/MainBoard/RADAR_Main_Board.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/MainBoard/RADAR_Main_Board.brd rename to schematics/4_6_Schematics/MainBoard/RADAR_Main_Board.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/MainBoard/RADAR_Main_Board.sch b/schematics/4_6_Schematics/MainBoard/RADAR_Main_Board.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/MainBoard/RADAR_Main_Board.sch rename to schematics/4_6_Schematics/MainBoard/RADAR_Main_Board.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/PowerAmplifierBoard/RF_PA.brd b/schematics/4_6_Schematics/PowerAmplifierBoard/RF_PA.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/PowerAmplifierBoard/RF_PA.brd rename to schematics/4_6_Schematics/PowerAmplifierBoard/RF_PA.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/PowerAmplifierBoard/RF_PA.sch b/schematics/4_6_Schematics/PowerAmplifierBoard/RF_PA.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/PowerAmplifierBoard/RF_PA.sch rename to schematics/4_6_Schematics/PowerAmplifierBoard/RF_PA.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/PowerBoard/PowerBoard.brd b/schematics/4_6_Schematics/PowerBoard/PowerBoard.brd similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/PowerBoard/PowerBoard.brd rename to schematics/4_6_Schematics/PowerBoard/PowerBoard.brd diff --git a/4_Schematics and Boards Layout/4_6_Schematics/PowerBoard/PowerBoard.sch b/schematics/4_6_Schematics/PowerBoard/PowerBoard.sch similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/PowerBoard/PowerBoard.sch rename to schematics/4_6_Schematics/PowerBoard/PowerBoard.sch diff --git a/4_Schematics and Boards Layout/4_6_Schematics/Stack_Hybrid.png b/schematics/4_6_Schematics/Stack_Hybrid.png similarity index 100% rename from 4_Schematics and Boards Layout/4_6_Schematics/Stack_Hybrid.png rename to schematics/4_6_Schematics/Stack_Hybrid.png diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx b/schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx rename to schematics/4_7_Production Files/Gerber_Main_Board/BOM_Main_Board.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/CPL.xlsx b/schematics/4_7_Production Files/Gerber_Main_Board/CPL.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/CPL.xlsx rename to schematics/4_7_Production Files/Gerber_Main_Board/CPL.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L1 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L1 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L1 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L1 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L10 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L10 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L10 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L10 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L2 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L2 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L2 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L2 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L3 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L3 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L3 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L3 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L4 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L4 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L4 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L4 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L5 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L5 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L5 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L5 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L6 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L6 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L6 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L6 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L7 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L7 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L7 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L7 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L8 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L8 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L8 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L8 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L9 b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L9 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L9 rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.L9 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bps b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bps rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bsk b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bsk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bsk rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.bsk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drd b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drd similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drd rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drd diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.dri b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.dri similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.dri rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.dri diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drl b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drl rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.drl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.gpi b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.gpi similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.gpi rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.gpi diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.oln b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.oln similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.oln rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.oln diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.slk b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.slk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.slk rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.slk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smb b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smb rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smt b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smt rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.smt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.tps b/schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.tps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.tps rename to schematics/4_7_Production Files/Gerber_Main_Board/RADAR_Main_Board.tps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/BOM.xlsx b/schematics/4_7_Production Files/Gerber_PA/BOM.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/BOM.xlsx rename to schematics/4_7_Production Files/Gerber_PA/BOM.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/BOM_PA.xlsx b/schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/BOM_PA.xlsx rename to schematics/4_7_Production Files/Gerber_PA/BOM_PA.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/CPL.xlsx b/schematics/4_7_Production Files/Gerber_PA/CPL.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/CPL.xlsx rename to schematics/4_7_Production Files/Gerber_PA/CPL.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L1 b/schematics/4_7_Production Files/Gerber_PA/RF_PA.L1 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L1 rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.L1 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L2 b/schematics/4_7_Production Files/Gerber_PA/RF_PA.L2 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L2 rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.L2 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L3 b/schematics/4_7_Production Files/Gerber_PA/RF_PA.L3 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L3 rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.L3 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L4 b/schematics/4_7_Production Files/Gerber_PA/RF_PA.L4 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.L4 rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.L4 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.adb b/schematics/4_7_Production Files/Gerber_PA/RF_PA.adb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.adb rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.adb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.adt b/schematics/4_7_Production Files/Gerber_PA/RF_PA.adt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.adt rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.adt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bgl b/schematics/4_7_Production Files/Gerber_PA/RF_PA.bgl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bgl rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.bgl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bps b/schematics/4_7_Production Files/Gerber_PA/RF_PA.bps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bps rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.bps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bsk b/schematics/4_7_Production Files/Gerber_PA/RF_PA.bsk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.bsk rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.bsk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.drd b/schematics/4_7_Production Files/Gerber_PA/RF_PA.drd similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.drd rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.drd diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.dri b/schematics/4_7_Production Files/Gerber_PA/RF_PA.dri similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.dri rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.dri diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.drl b/schematics/4_7_Production Files/Gerber_PA/RF_PA.drl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.drl rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.drl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.fab b/schematics/4_7_Production Files/Gerber_PA/RF_PA.fab similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.fab rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.fab diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.gpi b/schematics/4_7_Production Files/Gerber_PA/RF_PA.gpi similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.gpi rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.gpi diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.oln b/schematics/4_7_Production Files/Gerber_PA/RF_PA.oln similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.oln rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.oln diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.slk b/schematics/4_7_Production Files/Gerber_PA/RF_PA.slk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.slk rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.slk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.smb b/schematics/4_7_Production Files/Gerber_PA/RF_PA.smb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.smb rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.smb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.smt b/schematics/4_7_Production Files/Gerber_PA/RF_PA.smt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.smt rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.smt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.tgl b/schematics/4_7_Production Files/Gerber_PA/RF_PA.tgl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.tgl rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.tgl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.tps b/schematics/4_7_Production Files/Gerber_PA/RF_PA.tps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA.tps rename to schematics/4_7_Production Files/Gerber_PA/RF_PA.tps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA_MNB b/schematics/4_7_Production Files/Gerber_PA/RF_PA_MNB similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA_MNB rename to schematics/4_7_Production Files/Gerber_PA/RF_PA_MNB diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA_MNT b/schematics/4_7_Production Files/Gerber_PA/RF_PA_MNT similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PA/RF_PA_MNT rename to schematics/4_7_Production Files/Gerber_PA/RF_PA_MNT diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx b/schematics/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/BOM_Patch_Antenna.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/CPL.xlsx b/schematics/4_7_Production Files/Gerber_Patch_Antenna/CPL.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/CPL.xlsx rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/CPL.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L1 b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L1 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L1 rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L1 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L2 b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L2 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L2 rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L2 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L3 b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L3 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L3 rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L3 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L4 b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L4 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L4 rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.L4 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adb b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adb rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adt b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adt rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.adt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bps b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bps rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bsk b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bsk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bsk rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.bsk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drd b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drd similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drd rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drd diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.dri b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.dri similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.dri rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.dri diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drl b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drl rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.drl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.gpi b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.gpi similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.gpi rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.gpi diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnb b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnb rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnt b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnt rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.mnt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.oln b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.oln similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.oln rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.oln diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.slk b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.slk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.slk rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.slk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smb b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smb rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smt b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smt rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.smt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.tps b/schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.tps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.tps rename to schematics/4_7_Production Files/Gerber_Patch_Antenna/Patch_Anetnna_16_8.tps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/BOM.xlsx b/schematics/4_7_Production Files/Gerber_PowerBoard/BOM.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/BOM.xlsx rename to schematics/4_7_Production Files/Gerber_PowerBoard/BOM.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx b/schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx rename to schematics/4_7_Production Files/Gerber_PowerBoard/BOM_Power_Board.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/CPL.xlsx b/schematics/4_7_Production Files/Gerber_PowerBoard/CPL.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/CPL.xlsx rename to schematics/4_7_Production Files/Gerber_PowerBoard/CPL.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bot b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bot similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bot rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bot diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsk b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsk rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsp b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsp similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsp rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.bsp diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.csv b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.csv similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.csv rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.csv diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drd b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drd similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drd rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drd diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.dri b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.dri similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.dri rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.dri diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drl b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drl rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.drl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.gpi b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.gpi similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.gpi rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.gpi diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnb b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnb rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnt b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnt rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.mnt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.oln b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.oln similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.oln rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.oln diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.slk b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.slk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.slk rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.slk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smb b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smb rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smt b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smt rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.smt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.top b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.top similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.top rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.top diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.tsp b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.tsp similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard.tsp rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard.tsp diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard_CSV_BOM b/schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard_CSV_BOM similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_PowerBoard/PowerBoard_CSV_BOM rename to schematics/4_7_Production Files/Gerber_PowerBoard/PowerBoard_CSV_BOM diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx b/schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx rename to schematics/4_7_Production Files/Gerber_freq_synth/BOM_Freq_Synth.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/CPL.xlsx b/schematics/4_7_Production Files/Gerber_freq_synth/CPL.xlsx similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/CPL.xlsx rename to schematics/4_7_Production Files/Gerber_freq_synth/CPL.xlsx diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L1 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L1 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L1 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L1 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L2 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L2 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L2 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L2 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L3 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L3 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L3 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L3 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L4 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L4 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L4 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L4 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L5 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L5 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L5 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L5 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L6 b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L6 similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L6 rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.L6 diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bps b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bps rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bsk b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bsk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bsk rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.bsk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.csv b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.csv similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.csv rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.csv diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drd b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drd similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drd rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drd diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.dri b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.dri similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.dri rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.dri diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drl b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drl similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drl rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.drl diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.gpi b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.gpi similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.gpi rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.gpi diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnb b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnb rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnt b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnt rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.mnt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.oln b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.oln similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.oln rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.oln diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.slk b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.slk similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.slk rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.slk diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smb b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smb rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smt b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smt rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.smt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.tps b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.tps similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.tps rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board.tps diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_BOM_CSV b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_BOM_CSV similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_BOM_CSV rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_BOM_CSV diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnb b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnb similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnb rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnb diff --git a/4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnt b/schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnt similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnt rename to schematics/4_7_Production Files/Gerber_freq_synth/Clocks_Freq_Synth_board_mnt diff --git a/4_Schematics and Boards Layout/4_7_Production Files/PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf b/schematics/4_7_Production Files/PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf similarity index 100% rename from 4_Schematics and Boards Layout/4_7_Production Files/PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf rename to schematics/4_7_Production Files/PCBWay_Impedance_Note_RO4350B_h0p102mm.pdf diff --git a/simulate_city_defense_radar.py b/simulate_city_defense_radar.py deleted file mode 100644 index 8473458..0000000 --- a/simulate_city_defense_radar.py +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env python3 -""" -City Defense Radar Configuration Analysis -========================================== -Explores optimal radar placement for defending a city from jet-powered -Shahed missiles (Mach 0.4, ~136 m/s). - -Tests different configurations: -1. Perimeter defense (radars around city) -2. Centralized defense (radars at city center) -3. Mixed configuration -""" - -import numpy as np -from scipy.optimize import least_squares - -# ============================================================================= -# Constants -# ============================================================================= -MACH_04 = 136.0 # m/s (jet-powered Shahed) -RANGE_ACCURACY = 2.0 # meters -AZIMUTH_ACCURACY = 0.5 # degrees -ELEVATION_ACCURACY = 0.5 # degrees -UPDATE_RATE = 10.0 # Hz -TOTAL_FIXED_LATENCY = 0.0071 # 7.1ms - -# City parameters -CITY_RADIUS = 10000.0 # 10 km radius -RADAR_RANGE = 20000.0 # 20 km detection range (AERIS-10 spec) - -# Missile trajectory: approaching from north at low altitude -MISSILE_START = np.array([0.0, 40000.0, 2000.0]) # 40 km north, 2 km altitude -MISSILE_VELOCITY = np.array([0.0, -MACH_04, 0.0]) # Moving south toward city - -# ============================================================================= -# Radar Configurations -# ============================================================================= - -def get_perimeter_radar_positions(n_radars=4): - """Radars positioned around city perimeter.""" - positions = [] - for i in range(n_radars): - angle = 2 * np.pi * i / n_radars - x = CITY_RADIUS * np.cos(angle) - y = CITY_RADIUS * np.sin(angle) - positions.append(np.array([x, y, 0.0])) - return positions - -def get_central_radar_positions(n_radars=3): - """Radars positioned at city center (staggered).""" - positions = [] - for i in range(n_radars): - angle = 2 * np.pi * i / n_radars - x = 2000.0 * np.cos(angle) # 2 km from center - y = 2000.0 * np.sin(angle) - positions.append(np.array([x, y, 0.0])) - return positions - -def get_mixed_radar_positions(): - """Mixed: 2 perimeter + 2 central.""" - positions = [] - # Perimeter - positions.append(np.array([CITY_RADIUS, 0.0, 0.0])) - positions.append(np.array([-CITY_RADIUS, 0.0, 0.0])) - # Central - positions.append(np.array([2000.0, 2000.0, 0.0])) - positions.append(np.array([-2000.0, -2000.0, 0.0])) - return positions - -# ============================================================================= -# Helper Functions -# ============================================================================= - -def missile_position(t): - return MISSILE_START + MISSILE_VELOCITY * t - -def radar_measurement(radar_pos, target_pos, t, latency=0.0): - range_true = np.linalg.norm(target_pos - radar_pos) - dx = target_pos[0] - radar_pos[0] - dy = target_pos[1] - radar_pos[1] - dz = target_pos[2] - radar_pos[2] - azimuth_true = np.arctan2(dy, dx) * 180.0 / np.pi - elevation_true = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - range_vec = target_pos - radar_pos - range_unit = range_vec / range_true - doppler_true = np.dot(MISSILE_VELOCITY, range_unit) - - range_meas = range_true + np.random.normal(0, RANGE_ACCURACY) - azimuth_meas = azimuth_true + np.random.normal(0, AZIMUTH_ACCURACY) - elevation_meas = elevation_true + np.random.normal(0, ELEVATION_ACCURACY) - doppler_meas = doppler_true + np.random.normal(0, 1.0) - - return { - 'range': range_meas, - 'azimuth': azimuth_meas, - 'elevation': elevation_meas, - 'doppler': doppler_meas, - 'time': t - } - -def triangulate(measurements, radar_positions): - """Triangulate from multiple radar measurements.""" - def residuals(params): - x, y, z = params - est_pos = np.array([x, y, z]) - res = [] - for meas, rpos in zip(measurements, radar_positions): - range_est = np.linalg.norm(est_pos - rpos) - res.append(range_est - meas['range']) - - dx = x - rpos[0] - dy = y - rpos[1] - dz = z - rpos[2] - az_est = np.arctan2(dy, dx) * 180.0 / np.pi - el_est = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - res.append((az_est - meas['azimuth']) * range_est / 100.0) - res.append((el_est - meas['elevation']) * range_est / 100.0) - return res - - # Initial guess: average of radar positions - x0 = np.mean([p[0] for p in radar_positions]) - y0 = np.mean([p[1] for p in radar_positions]) - z0 = 2000.0 # Guess altitude - - result = least_squares(residuals, [x0, y0, z0]) - return result.x - -# ============================================================================= -# Main Simulation -# ============================================================================= - -print("=" * 80) -print("City Defense Radar Configuration Analysis") -print("=" * 80) -print(f"Missile: Jet-powered Shahed ({MACH_04} m/s, Mach 0.4)") -print(f"City radius: {CITY_RADIUS/1000:.0f} km") -print(f"Missile approach: From north at 2 km altitude") -print() - -# Test different configurations -configs = { - "2 perimeter": get_perimeter_radar_positions(2), - "4 perimeter": get_perimeter_radar_positions(4), - "3 central": get_central_radar_positions(3), - "4 mixed": get_mixed_radar_positions(), -} - -# Simulate missile approach -sim_duration = 300.0 # 5 minutes -times = np.arange(0, sim_duration, 1.0) # 1 Hz for simplicity - -print("=" * 80) -print("Tracking Accuracy by Configuration") -print("=" * 80) -print() - -for config_name, radar_positions in configs.items(): - errors = [] - for t in times: - true_pos = missile_position(t) - - # Check if missile is within range of at least 2 radars - in_range = 0 - for rpos in radar_positions: - if np.linalg.norm(true_pos - rpos) < RADAR_RANGE: - in_range += 1 - - if in_range < 2: - continue - - # Get measurements from all radars in range - measurements = [] - active_positions = [] - for rpos in radar_positions: - if np.linalg.norm(true_pos - rpos) < RADAR_RANGE: - meas = radar_measurement(rpos, true_pos, t, TOTAL_FIXED_LATENCY) - measurements.append(meas) - active_positions.append(rpos) - - # Triangulate - est_pos = triangulate(measurements, active_positions) - error = np.linalg.norm(true_pos - est_pos) - errors.append(error) - - if errors: - errors = np.array(errors) - print(f"{config_name:<15} | Mean: {np.mean(errors):7.1f}m | 95th: {np.percentile(errors, 95):7.1f}m | Max: {np.max(errors):7.1f}m") - else: - print(f"{config_name:<15} | No coverage") - -print() -print("=" * 80) -print("Early Warning Time Analysis") -print("=" * 80) -print() - -for config_name, radar_positions in configs.items(): - # Find first time missile is detected by 2+ radars - detection_time = None - for t in times: - true_pos = missile_position(t) - in_range = 0 - for rpos in radar_positions: - if np.linalg.norm(true_pos - rpos) < RADAR_RANGE: - in_range += 1 - if in_range >= 2: - detection_time = t - break - - if detection_time is not None: - # Time to impact (when missile reaches city center) - time_to_impact = 200000.0 / MACH_04 # 200 km / 136 m/s - warning_time = time_to_impact - detection_time - print(f"{config_name:<15} | Detection at t={detection_time:5.0f}s | Warning time: {warning_time/60:.1f} min") - else: - print(f"{config_name:<15} | No detection") - -print() -print("=" * 80) -print("Recommendations") -print("=" * 80) -print() -print("For city defense against jet-powered Shahed missiles:") -print() -print("1. PERIMETER RADARS provide better early warning") -print(" - Detect missiles farther from city") -print(" - More time for interception") -print() -print("2. CENTRAL RADARS provide better tracking accuracy") -print(" - Closer to target = better SNR") -print(" - Better angular resolution") -print() -print("3. MIXED CONFIGURATION is optimal") -print(" - Perimeter radars for early warning") -print(" - Central radars for precise tracking") -print(" - Redundancy if one radar is destroyed") -print() -print("For a 10 km radius city:") -print("- 4 perimeter radars at cardinal points") -print("- 2-3 central radars for tracking") -print("- Total: 6-7 radars for robust defense") diff --git a/simulate_dual_radar_tracking.py b/simulate_dual_radar_tracking.py deleted file mode 100644 index 4e7413e..0000000 --- a/simulate_dual_radar_tracking.py +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/env python3 -""" -Dual Radar Projectile Tracking Simulation -========================================== -Simulates two GPS-synced AERIS-10 radars tracking a projectile at Mach 0.8. -Models hardware latency and tests triangulation accuracy. - -Projectile: Mach 0.8 (~272 m/s at sea level) -Radars: Two AERIS-10 units at known positions -Goal: Validate triangulation precision and latency compensation -""" - -import numpy as np -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -from scipy.optimize import least_squares -import time - -# ============================================================================= -# Constants -# ============================================================================= -SPEED_OF_LIGHT = 299792458.0 # m/s -MACH_08 = 272.0 # m/s at sea level - -# Radar hardware parameters (from AERIS-10 specs) -RANGE_ACCURACY = 2.0 # meters (typical for FMCW at this bandwidth) -AZIMUTH_ACCURACY = 0.5 # degrees -ELEVATION_ACCURACY = 0.5 # degrees -DOPPLER_ACCURACY = 1.0 # m/s -UPDATE_RATE = 10.0 # Hz (100ms between updates) - -# Hardware latency components (seconds) -LATENCY_PROPAGATION = 0.0 # Will be calculated based on distance -LATENCY_SIGNAL_PROCESSING = 0.005 # 5ms for FFT, pulse compression -LATENCY_DATA_TRANSMISSION = 0.002 # 2ms FPGA to host -LATENCY_SYNC_ERROR = 0.0001 # 100us GPS sync residual error -TOTAL_FIXED_LATENCY = (LATENCY_SIGNAL_PROCESSING + LATENCY_DATA_TRANSMISSION + - LATENCY_SYNC_ERROR) - -# ============================================================================= -# Simulation Parameters -# ============================================================================= -SIM_DURATION = 5.0 # seconds -DT = 0.01 # 10ms time step for simulation -BASELINE_DISTANCE = 5000.0 # 5km between radars - -# Radar positions (meters) -RADAR1_POS = np.array([0.0, 0.0, 0.0]) -RADAR2_POS = np.array([BASELINE_DISTANCE, 0.0, 0.0]) - -# Projectile trajectory: straight line at Mach 0.8 -# Starting position and velocity vector -PROJECTILE_START = np.array([2500.0, 1000.0, 500.0]) # Between radars, elevated -PROJECTILE_VELOCITY = np.array([MACH_08, 0.0, 0.0]) # Moving along x-axis - -# ============================================================================= -# Helper Functions -# ============================================================================= - -def projectile_position(t): - """Calculate projectile position at time t.""" - return PROJECTILE_START + PROJECTILE_VELOCITY * t - -def radar_measurement(radar_pos, target_pos, t, latency=0.0): - """ - Simulate radar measurement of target. - Returns (range, azimuth, elevation, doppler) with noise and latency. - """ - # Calculate true range - range_true = np.linalg.norm(target_pos - radar_pos) - - # Calculate true azimuth and elevation - dx = target_pos[0] - radar_pos[0] - dy = target_pos[1] - radar_pos[1] - dz = target_pos[2] - radar_pos[2] - - azimuth_true = np.arctan2(dy, dx) * 180.0 / np.pi - elevation_true = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - - # Calculate true Doppler (radial velocity) - range_vec = target_pos - radar_pos - range_unit = range_vec / range_true - doppler_true = np.dot(PROJECTILE_VELOCITY, range_unit) - - # Add measurement noise - range_meas = range_true + np.random.normal(0, RANGE_ACCURACY) - azimuth_meas = azimuth_true + np.random.normal(0, AZIMUTH_ACCURACY) - elevation_meas = elevation_true + np.random.normal(0, ELEVATION_ACCURACY) - doppler_meas = doppler_true + np.random.normal(0, DOPPLER_ACCURACY) - - # Apply latency: radar sees target at earlier time - target_pos_delayed = projectile_position(t - latency) - - return { - 'range': range_meas, - 'azimuth': azimuth_meas, - 'elevation': elevation_meas, - 'doppler': doppler_meas, - 'range_true': range_true, - 'time': t, - 'target_pos_delayed': target_pos_delayed - } - -def triangulate(r1_meas, r2_meas, r1_pos, r2_pos): - """ - Triangulate target position from two radar measurements. - Uses least-squares optimization with range, azimuth, and elevation. - """ - def residuals(params): - """Residuals for least-squares optimization.""" - x, y, z = params - - # Calculate range from each radar to estimated position - est_pos = np.array([x, y, z]) - range1_est = np.linalg.norm(est_pos - r1_pos) - range2_est = np.linalg.norm(est_pos - r2_pos) - - # Calculate azimuth and elevation from each radar - dx1 = x - r1_pos[0] - dy1 = y - r1_pos[1] - dz1 = z - r1_pos[2] - az1_est = np.arctan2(dy1, dx1) * 180.0 / np.pi - el1_est = np.arctan2(dz1, np.sqrt(dx1**2 + dy1**2)) * 180.0 / np.pi - - dx2 = x - r2_pos[0] - dy2 = y - r2_pos[1] - dz2 = z - r2_pos[2] - az2_est = np.arctan2(dy2, dx2) * 180.0 / np.pi - el2_est = np.arctan2(dz2, np.sqrt(dx2**2 + dy2**2)) * 180.0 / np.pi - - # Residuals: difference between measured and estimated values - return [ - range1_est - r1_meas['range'], - range2_est - r2_meas['range'], - (az1_est - r1_meas['azimuth']) * range1_est / 100.0, # Scale angle error by range - (az2_est - r2_meas['azimuth']) * range2_est / 100.0, - (el1_est - r1_meas['elevation']) * range1_est / 100.0, - (el2_est - r2_meas['elevation']) * range2_est / 100.0, - ] - - # Initial guess: midpoint between radars at target elevation - x0 = (r1_pos[0] + r2_pos[0]) / 2.0 - y0 = (r1_pos[1] + r2_pos[1]) / 2.0 - z0 = r1_meas['target_pos_delayed'][2] - - result = least_squares(residuals, [x0, y0, z0]) - return result.x - -# ============================================================================= -# Main Simulation -# ============================================================================= - -print("=" * 80) -print("Dual Radar Projectile Tracking Simulation") -print("=" * 80) -print(f"Projectile: Mach 0.8 ({MACH_08} m/s)") -print(f"Radar baseline: {BASELINE_DISTANCE/1000:.1f} km") -print(f"Simulation duration: {SIM_DURATION}s") -print(f"Update rate: {UPDATE_RATE} Hz") -print(f"Total fixed latency: {TOTAL_FIXED_LATENCY*1000:.1f} ms") -print() - -# Run simulation -times = np.arange(0, SIM_DURATION, 1.0/UPDATE_RATE) -errors = [] -positions_true = [] -positions_estimated = [] - -for t in times: - # Get true projectile position - true_pos = projectile_position(t) - positions_true.append(true_pos.copy()) - - # Simulate radar measurements with latency - r1_meas = radar_measurement(RADAR1_POS, true_pos, t, TOTAL_FIXED_LATENCY) - r2_meas = radar_measurement(RADAR2_POS, true_pos, t, TOTAL_FIXED_LATENCY) - - # Triangulate - estimated_pos = triangulate(r1_meas, r2_meas, RADAR1_POS, RADAR2_POS) - positions_estimated.append(estimated_pos) - - # Calculate error - error = np.linalg.norm(true_pos - estimated_pos) - errors.append(error) - - # Print progress - if len(times) <= 10 or t == times[-1]: - print(f"t={t:4.1f}s | True: [{true_pos[0]:7.0f}, {true_pos[1]:7.0f}, {true_pos[2]:7.0f}] | " - f"Est: [{estimated_pos[0]:7.0f}, {estimated_pos[1]:7.0f}, {estimated_pos[2]:7.0f}] | " - f"Error: {error:6.2f}m") - -# ============================================================================= -# Results Analysis -# ============================================================================= - -errors = np.array(errors) -print() -print("=" * 80) -print("Results Summary") -print("=" * 80) -print(f"Mean position error: {np.mean(errors):.2f} m") -print(f"Median position error: {np.median(errors):.2f} m") -print(f"Max position error: {np.max(errors):.2f} m") -print(f"Std deviation: {np.std(errors):.2f} m") -print(f"95th percentile: {np.percentile(errors, 95):.2f} m") -print() - -# ============================================================================= -# Visualization -# ============================================================================= - -fig, axes = plt.subplots(2, 2, figsize=(15, 12)) - -# Plot 1: Top-down view of trajectory and radar positions -ax1 = axes[0, 0] -positions_true = np.array(positions_true) -positions_estimated = np.array(positions_estimated) - -ax1.plot(positions_true[:, 0], positions_true[:, 1], 'b-', label='True trajectory') -ax1.plot(positions_estimated[:, 0], positions_estimated[:, 1], 'r--', label='Estimated') -ax1.plot(RADAR1_POS[0], RADAR1_POS[1], 'go', markersize=10, label='Radar 1') -ax1.plot(RADAR2_POS[0], RADAR2_POS[1], 'go', markersize=10, label='Radar 2') -ax1.set_xlabel('X (m)') -ax1.set_ylabel('Y (m)') -ax1.set_title('Top-Down View: True vs Estimated Trajectory') -ax1.legend() -ax1.grid(True) -ax1.set_aspect('equal') - -# Plot 2: Position error over time -ax2 = axes[0, 1] -ax2.plot(times, errors, 'r-o', markersize=3) -ax2.set_xlabel('Time (s)') -ax2.set_ylabel('Position Error (m)') -ax2.set_title('Position Error Over Time') -ax2.grid(True) -ax2.axhline(y=np.mean(errors), color='blue', linestyle='--', label=f'Mean: {np.mean(errors):.1f}m') -ax2.legend() - -# Plot 3: 3D trajectory -ax3 = axes[1, 0] -ax3.plot(positions_true[:, 0], positions_true[:, 1], positions_true[:, 2], 'b-', label='True') -ax3.plot(positions_estimated[:, 0], positions_estimated[:, 1], positions_estimated[:, 2], 'r--', label='Estimated') -ax3.plot([RADAR1_POS[0], RADAR2_POS[0]], [RADAR1_POS[1], RADAR2_POS[1]], [RADAR1_POS[2], RADAR2_POS[2]], 'go', label='Radars') -ax3.set_xlabel('X (m)') -ax3.set_ylabel('Y (m)') -if hasattr(ax3, 'set_zlabel'): - ax3.set_zlabel('Z (m)') -ax3.set_title('3D Trajectory') -ax3.legend() - -# Plot 4: Error distribution -ax4 = axes[1, 1] -ax4.hist(errors, bins=20, edgecolor='black') -ax4.set_xlabel('Position Error (m)') -ax4.set_ylabel('Frequency') -ax4.set_title('Error Distribution') -ax4.grid(True) - -plt.tight_layout() -plt.savefig('dual_radar_tracking_results.png', dpi=150) -print("Results saved to: dual_radar_tracking_results.png") -plt.show() - -print() -print("Simulation complete.") diff --git a/simulate_interceptor_drones.py b/simulate_interceptor_drones.py deleted file mode 100644 index 308c58a..0000000 --- a/simulate_interceptor_drones.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python3 -""" -Interceptor Drone Swarm vs Shahed Missile Simulation -===================================================== -Simulates 3 pre-positioned interceptor drones that fly in the same -direction as the Shahed missile, using IR tracking to home in and collide. - -Key concept: Lower delta speed gives more time for AI adjustments. -3-drone formation absorbs radar positioning errors. -""" - -import numpy as np - -# ============================================================================= -# Constants -# ============================================================================= -SHAHED_SPEED = 136.0 # m/s (jet-powered Shahed) -INTERCEPTOR_SPEED = 100.0 # m/s (slower, but same direction) -IR_TRACKING_RANGE = 5000.0 # 5 km -IR_HOMING_ACCURACY = 5.0 # degrees -RADAR_POSITION_ERROR = 20.0 # meters (mean) -DRONE_FORMATION_SPACING = 50.0 # meters between drones - -# Simulation parameters -DT = 0.1 # 100 ms time step -SIM_DURATION = 300.0 # 5 minutes - -# ============================================================================= -# Scenario Setup -# ============================================================================= - -# Shahed trajectory: approaching city from north -SHAHED_START = np.array([0.0, 40000.0, 2000.0]) # 40 km north, 2 km altitude -SHAHED_VELOCITY = np.array([0.0, -SHAHED_SPEED, 0.0]) # Moving south - -# Interceptor drone launch positions (pre-positioned around terrain) -# Positioned to intercept Shahed at ~10 km from city -INTERCEPTOR_LAUNCH_POS = np.array([0.0, 15000.0, 1500.0]) - -# Radar-detected trajectory (with error) -def get_radar_trajectory(): - """Simulate radar-detected trajectory with positioning error.""" - error = np.random.normal(0, RADAR_POSITION_ERROR, 3) - detected_start = SHAHED_START + error - return detected_start, SHAHED_VELOCITY - -# ============================================================================= -# Simulation Functions -# ============================================================================= - -def shahed_position(t): - """True Shahed position at time t.""" - return SHAHED_START + SHAHED_VELOCITY * t - -def drone_position(t, launch_time, velocity): - """Interceptor drone position at time t.""" - if t < launch_time: - return INTERCEPTOR_LAUNCH_POS - return INTERCEPTOR_LAUNCH_POS + velocity * (t - launch_time) - -def ir_tracking_error(distance): - """IR tracking error decreases with closer distance.""" - base_error = IR_HOMING_ACCURACY - if distance < 1000: - return base_error * 0.5 - elif distance < 2000: - return base_error * 0.75 - return base_error - -def simulate_interception(): - """Simulate the interception scenario.""" - print("=" * 80) - print("Interceptor Drone Swarm vs Shahed Missile Simulation") - print("=" * 80) - print(f"Shahed speed: {SHAHED_SPEED} m/s") - print(f"Interceptor speed: {INTERCEPTOR_SPEED} m/s") - print(f"IR tracking range: {IR_TRACKING_RANGE/1000:.0f} km") - print(f"Radar position error: {RADAR_POSITION_ERROR} m") - print() - - # Get radar-detected trajectory - detected_start, detected_velocity = get_radar_trajectory() - radar_error = np.linalg.norm(detected_start - SHAHED_START) - print(f"Radar detected Shahed with {radar_error:.1f} m position error") - print() - - # Calculate interception point based on radar data - # Drones fly to intercept at ~10 km from city - intercept_distance = 10000.0 # 10 km from city center - intercept_time = (40000.0 - intercept_distance) / SHAHED_SPEED - intercept_point = SHAHED_START + SHAHED_VELOCITY * intercept_time - - print(f"Predicted interception point: {intercept_point[1]/1000:.0f} km from city") - print(f"Predicted interception time: {intercept_time:.0f} s") - print() - - # Launch 3 interceptor drones in formation - # Middle drone is the "killer", flank drones provide IR tracking - drone_positions = [ - INTERCEPTOR_LAUNCH_POS + np.array([DRONE_FORMATION_SPACING, 0, 0]), # Left - INTERCEPTOR_LAUNCH_POS, # Middle (killer) - INTERCEPTOR_LAUNCH_POS + np.array([-DRONE_FORMATION_SPACING, 0, 0]), # Right - ] - - # Calculate drone velocity to reach interception point - drone_travel_time = intercept_time - 30.0 # 30s reaction time - if drone_travel_time <= 0: - print("ERROR: Not enough time for drones to reach interception point") - return - - drone_velocity = (intercept_point - INTERCEPTOR_LAUNCH_POS) / drone_travel_time - drone_speed = np.linalg.norm(drone_velocity) - print(f"Drone velocity: {drone_speed:.1f} m/s") - print() - - # Simulate the interception - print("Simulation:") - print("-" * 80) - - t = 0.0 - while t < SIM_DURATION: - shahed_pos = shahed_position(t) - - # Check if Shahed is within IR tracking range of drones - drone_pos = drone_positions[1] # Middle drone - if t > 30.0: # After launch - drone_pos = INTERCEPTOR_LAUNCH_POS + drone_velocity * (t - 30.0) - - distance = np.linalg.norm(shahed_pos - drone_pos) - - if distance < IR_TRACKING_RANGE: - # IR tracking active - tracking_error = ir_tracking_error(distance) - - # Drones adjust based on IR tracking - # Simulate homing correction - correction_factor = 1.0 - (distance / IR_TRACKING_RANGE) - actual_drone_pos = drone_pos + (shahed_pos - drone_pos) * correction_factor * 0.1 - - # Check for collision (middle drone) - if distance < 10.0: # 10 m collision radius - print(f"t={t:6.1f}s | COLLISION! Distance: {distance:.1f} m") - print(f"Shahed destroyed at {shahed_pos[1]/1000:.0f} km from city") - return True - - # Print status every 10 seconds - if int(t) % 10 == 0 and t > 0: - print(f"t={t:6.1f}s | Shahed: {shahed_pos[1]/1000:6.1f} km | Drone: {np.linalg.norm(drone_pos)/1000:6.1f} km | Distance: {distance/1000:6.1f} km") - - t += DT - - print(f"t={t:6.1f}s | Shahed reached city without interception") - return False - -# ============================================================================= -# Monte Carlo Simulation -# ============================================================================= - -def monte_carlo_simulation(n_trials=100): - """Run multiple simulations with different radar errors.""" - print("=" * 80) - print(f"Monte Carlo Simulation ({n_trials} trials)") - print("=" * 80) - print() - - successes = 0 - for i in range(n_trials): - # Reset random seed for reproducibility - np.random.seed(i) - - if simulate_interception(): - successes += 1 - - # Only print detailed output for first few trials - if i >= 2: - break - - # Run remaining trials silently - for i in range(3, n_trials): - np.random.seed(i) - # Simplified simulation for speed - radar_error = np.random.normal(0, RADAR_POSITION_ERROR) - # Success if radar error is small enough - if abs(radar_error) < 50.0: - successes += 1 - - success_rate = 100.0 * successes / n_trials - print() - print("=" * 80) - print(f"Results: {successes}/{n_trials} successful interceptions ({success_rate:.1f}%)") - print("=" * 80) - print() - print("Key factors affecting success:") - print(f"1. Radar position error: {RADAR_POSITION_ERROR} m (mean)") - print(f"2. IR homing accuracy: {IR_HOMING_ACCURACY} degrees") - print(f"3. Drone formation spacing: {DRONE_FORMATION_SPACING} m") - print(f"4. Interceptor speed: {INTERCEPTOR_SPEED} m/s") - print() - print("The 3-drone formation helps absorb radar errors because:") - print("- Flank drones provide wider IR coverage") - print("- Middle drone can adjust based on relative positions") - print("- Redundancy if one drone misses") - -# ============================================================================= -# Main -# ============================================================================= - -if __name__ == "__main__": - # Run single detailed simulation - simulate_interception() - print() - - # Run Monte Carlo simulation - monte_carlo_simulation(100) diff --git a/simulate_three_radar_tracking.py b/simulate_three_radar_tracking.py deleted file mode 100644 index 47e7745..0000000 --- a/simulate_three_radar_tracking.py +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env python3 -""" -Three Radar vs Two Radar Tracking Comparison -============================================ -Tests whether adding a third radar improves tracking precision -for a Mach 0.8 projectile. -""" - -import numpy as np -from scipy.optimize import least_squares - -# ============================================================================= -# Constants -# ============================================================================= -MACH_08 = 272.0 # m/s -RANGE_ACCURACY = 2.0 # meters -AZIMUTH_ACCURACY = 0.5 # degrees -ELEVATION_ACCURACY = 0.5 # degrees -DOPPLER_ACCURACY = 1.0 # m/s -UPDATE_RATE = 10.0 # Hz -TOTAL_FIXED_LATENCY = 0.0071 # 7.1ms -SIM_DURATION = 10.0 # seconds -BASELINE_DISTANCE = 5000.0 # 5km - -# Radar positions -RADAR1_POS = np.array([0.0, 0.0, 0.0]) -RADAR2_POS = np.array([BASELINE_DISTANCE, 0.0, 0.0]) -RADAR3_POS = np.array([2500.0, 4000.0, 0.0]) # Third radar forming triangle - -# Projectile trajectory -PROJECTILE_START = np.array([2500.0, 1000.0, 500.0]) -PROJECTILE_VELOCITY = np.array([MACH_08, 0.0, 0.0]) - -# ============================================================================= -# Helper Functions -# ============================================================================= - -def projectile_position(t): - return PROJECTILE_START + PROJECTILE_VELOCITY * t - -def radar_measurement(radar_pos, target_pos, t, latency=0.0): - range_true = np.linalg.norm(target_pos - radar_pos) - dx = target_pos[0] - radar_pos[0] - dy = target_pos[1] - radar_pos[1] - dz = target_pos[2] - radar_pos[2] - azimuth_true = np.arctan2(dy, dx) * 180.0 / np.pi - elevation_true = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - range_vec = target_pos - radar_pos - range_unit = range_vec / range_true - doppler_true = np.dot(PROJECTILE_VELOCITY, range_unit) - - range_meas = range_true + np.random.normal(0, RANGE_ACCURACY) - azimuth_meas = azimuth_true + np.random.normal(0, AZIMUTH_ACCURACY) - elevation_meas = elevation_true + np.random.normal(0, ELEVATION_ACCURACY) - doppler_meas = doppler_true + np.random.normal(0, DOPPLER_ACCURACY) - - return { - 'range': range_meas, - 'azimuth': azimuth_meas, - 'elevation': elevation_meas, - 'doppler': doppler_meas, - 'time': t - } - -def triangulate_two_radar(r1_meas, r2_meas, r1_pos, r2_pos): - def residuals(params): - x, y, z = params - est_pos = np.array([x, y, z]) - range1_est = np.linalg.norm(est_pos - r1_pos) - range2_est = np.linalg.norm(est_pos - r2_pos) - - dx1 = x - r1_pos[0] - dy1 = y - r1_pos[1] - dz1 = z - r1_pos[2] - az1_est = np.arctan2(dy1, dx1) * 180.0 / np.pi - el1_est = np.arctan2(dz1, np.sqrt(dx1**2 + dy1**2)) * 180.0 / np.pi - - dx2 = x - r2_pos[0] - dy2 = y - r2_pos[1] - dz2 = z - r2_pos[2] - az2_est = np.arctan2(dy2, dx2) * 180.0 / np.pi - el2_est = np.arctan2(dz2, np.sqrt(dx2**2 + dy2**2)) * 180.0 / np.pi - - return [ - range1_est - r1_meas['range'], - range2_est - r2_meas['range'], - (az1_est - r1_meas['azimuth']) * range1_est / 100.0, - (az2_est - r2_meas['azimuth']) * range2_est / 100.0, - (el1_est - r1_meas['elevation']) * range1_est / 100.0, - (el2_est - r2_meas['elevation']) * range2_est / 100.0, - ] - - x0 = (r1_pos[0] + r2_pos[0]) / 2.0 - y0 = (r1_pos[1] + r2_pos[1]) / 2.0 - z0 = 500.0 - result = least_squares(residuals, [x0, y0, z0]) - return result.x - -def triangulate_three_radar(r1_meas, r2_meas, r3_meas, r1_pos, r2_pos, r3_pos): - def residuals(params): - x, y, z = params - est_pos = np.array([x, y, z]) - range1_est = np.linalg.norm(est_pos - r1_pos) - range2_est = np.linalg.norm(est_pos - r2_pos) - range3_est = np.linalg.norm(est_pos - r3_pos) - - residuals = [ - range1_est - r1_meas['range'], - range2_est - r2_meas['range'], - range3_est - r3_meas['range'], - ] - - # Add azimuth/elevation for all three radars - for i, (r_meas, r_pos) in enumerate([(r1_meas, r1_pos), (r2_meas, r2_pos), (r3_meas, r3_pos)]): - dx = x - r_pos[0] - dy = y - r_pos[1] - dz = z - r_pos[2] - range_est = np.linalg.norm(est_pos - r_pos) - az_est = np.arctan2(dy, dx) * 180.0 / np.pi - el_est = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - residuals.append((az_est - r_meas['azimuth']) * range_est / 100.0) - residuals.append((el_est - r_meas['elevation']) * range_est / 100.0) - - return residuals - - x0 = (r1_pos[0] + r2_pos[0] + r3_pos[0]) / 3.0 - y0 = (r1_pos[1] + r2_pos[1] + r3_pos[1]) / 3.0 - z0 = 500.0 - result = least_squares(residuals, [x0, y0, z0]) - return result.x - -# ============================================================================= -# Main Simulation -# ============================================================================= - -print("=" * 80) -print("Three Radar vs Two Radar Tracking Comparison") -print("=" * 80) -print(f"Projectile: Mach 0.8 ({MACH_08} m/s)") -print(f"Radar baseline: {BASELINE_DISTANCE/1000:.1f} km") -print(f"Third radar position: {RADAR3_POS}") -print() - -# Run simulation with both configurations -times = np.arange(0, SIM_DURATION, 1.0/UPDATE_RATE) -errors_two_radar = [] -errors_three_radar = [] - -for t in times: - true_pos = projectile_position(t) - - # Two radar measurements - r1_meas = radar_measurement(RADAR1_POS, true_pos, t, TOTAL_FIXED_LATENCY) - r2_meas = radar_measurement(RADAR2_POS, true_pos, t, TOTAL_FIXED_LATENCY) - - # Two radar triangulation - est_two = triangulate_two_radar(r1_meas, r2_meas, RADAR1_POS, RADAR2_POS) - error_two = np.linalg.norm(true_pos - est_two) - errors_two_radar.append(error_two) - - # Three radar measurements (reuse r1, r2, add r3) - r3_meas = radar_measurement(RADAR3_POS, true_pos, t, TOTAL_FIXED_LATENCY) - - # Three radar triangulation - est_three = triangulate_three_radar(r1_meas, r2_meas, r3_meas, RADAR1_POS, RADAR2_POS, RADAR3_POS) - error_three = np.linalg.norm(true_pos - est_three) - errors_three_radar.append(error_three) - -# ============================================================================= -# Results Analysis -# ============================================================================= - -errors_two_radar = np.array(errors_two_radar) -errors_three_radar = np.array(errors_three_radar) - -print("=" * 80) -print("Results Comparison") -print("=" * 80) -print() -print(f"{'Metric':<30} {'Two Radars':<15} {'Three Radars':<15} {'Improvement':<15}") -print("-" * 75) -print(f"{'Mean error (m)':<30} {np.mean(errors_two_radar):<15.2f} {np.mean(errors_three_radar):<15.2f} {100*(1-np.mean(errors_three_radar)/np.mean(errors_two_radar)):<15.1f}%") -print(f"{'Median error (m)':<30} {np.median(errors_two_radar):<15.2f} {np.median(errors_three_radar):<15.2f} {100*(1-np.median(errors_three_radar)/np.median(errors_two_radar)):<15.1f}%") -print(f"{'Max error (m)':<30} {np.max(errors_two_radar):<15.2f} {np.max(errors_three_radar):<15.2f} {100*(1-np.max(errors_three_radar)/np.max(errors_two_radar)):<15.1f}%") -print(f"{'95th percentile (m)':<30} {np.percentile(errors_two_radar, 95):<15.2f} {np.percentile(errors_three_radar, 95):<15.2f} {100*(1-np.percentile(errors_three_radar, 95)/np.percentile(errors_two_radar, 95)):<15.1f}%") -print() - -# Statistical test -t_stat = (np.mean(errors_two_radar) - np.mean(errors_three_radar)) / (np.std(errors_two_radar - errors_three_radar) / np.sqrt(len(times))) -print(f"Paired t-test statistic: {t_stat:.2f}") -print(f"p-value (approx): {2*(1-np.cumsum(np.exp(-0.5*np.arange(1000)**2))*2/np.sqrt(2*np.pi))[-1]:.4f}") -print() - -print("=" * 80) -print("Conclusion") -print("=" * 80) -improvement = 100 * (1 - np.mean(errors_three_radar) / np.mean(errors_two_radar)) -print(f"Adding a third radar improves mean position error by {improvement:.1f}%") -print(f"(from {np.mean(errors_two_radar):.1f}m to {np.mean(errors_three_radar):.1f}m)") -print() -print("The improvement comes from:") -print("1. More redundant measurements (9 vs 6)") -print("2. Better geometric coverage (triangle vs line)") -print("3. Reduced sensitivity to individual measurement errors") diff --git a/simulate_trajectory_precision.py b/simulate_trajectory_precision.py deleted file mode 100644 index 090ea56..0000000 --- a/simulate_trajectory_precision.py +++ /dev/null @@ -1,240 +0,0 @@ -#!/usr/bin/env python3 -""" -Trajectory Precision Analysis for Dual Radar Projectile Tracking -================================================================ -Analyzes how well two GPS-synced radars can reconstruct the complete -trajectory of a Mach 0.8 projectile, including velocity estimation. -""" - -import numpy as np -from scipy.optimize import least_squares - -# ============================================================================= -# Constants -# ============================================================================= -SPEED_OF_LIGHT = 299792458.0 # m/s -MACH_08 = 272.0 # m/s at sea level - -# Radar hardware parameters -RANGE_ACCURACY = 2.0 # meters -AZIMUTH_ACCURACY = 0.5 # degrees -ELEVATION_ACCURACY = 0.5 # degrees -DOPPLER_ACCURACY = 1.0 # m/s -UPDATE_RATE = 10.0 # Hz - -# Hardware latency -TOTAL_FIXED_LATENCY = 0.0071 # 7.1ms - -# Simulation parameters -SIM_DURATION = 10.0 # seconds (longer for trajectory analysis) -BASELINE_DISTANCE = 5000.0 # 5km - -# Radar positions -RADAR1_POS = np.array([0.0, 0.0, 0.0]) -RADAR2_POS = np.array([BASELINE_DISTANCE, 0.0, 0.0]) - -# Projectile trajectory: straight line at Mach 0.8 -PROJECTILE_START = np.array([2500.0, 1000.0, 500.0]) -PROJECTILE_VELOCITY = np.array([MACH_08, 0.0, 0.0]) - -# ============================================================================= -# Helper Functions -# ============================================================================= - -def projectile_position(t): - """Calculate projectile position at time t.""" - return PROJECTILE_START + PROJECTILE_VELOCITY * t - -def radar_measurement(radar_pos, target_pos, t, latency=0.0): - """Simulate radar measurement with noise and latency.""" - range_true = np.linalg.norm(target_pos - radar_pos) - - dx = target_pos[0] - radar_pos[0] - dy = target_pos[1] - radar_pos[1] - dz = target_pos[2] - radar_pos[2] - - azimuth_true = np.arctan2(dy, dx) * 180.0 / np.pi - elevation_true = np.arctan2(dz, np.sqrt(dx**2 + dy**2)) * 180.0 / np.pi - - range_vec = target_pos - radar_pos - range_unit = range_vec / range_true - doppler_true = np.dot(PROJECTILE_VELOCITY, range_unit) - - # Add measurement noise - range_meas = range_true + np.random.normal(0, RANGE_ACCURACY) - azimuth_meas = azimuth_true + np.random.normal(0, AZIMUTH_ACCURACY) - elevation_meas = elevation_true + np.random.normal(0, ELEVATION_ACCURACY) - doppler_meas = doppler_true + np.random.normal(0, DOPPLER_ACCURACY) - - return { - 'range': range_meas, - 'azimuth': azimuth_meas, - 'elevation': elevation_meas, - 'doppler': doppler_meas, - 'time': t - } - -def triangulate(r1_meas, r2_meas, r1_pos, r2_pos): - """Triangulate target position from two radar measurements.""" - def residuals(params): - x, y, z = params - est_pos = np.array([x, y, z]) - range1_est = np.linalg.norm(est_pos - r1_pos) - range2_est = np.linalg.norm(est_pos - r2_pos) - - dx1 = x - r1_pos[0] - dy1 = y - r1_pos[1] - dz1 = z - r1_pos[2] - az1_est = np.arctan2(dy1, dx1) * 180.0 / np.pi - el1_est = np.arctan2(dz1, np.sqrt(dx1**2 + dy1**2)) * 180.0 / np.pi - - dx2 = x - r2_pos[0] - dy2 = y - r2_pos[1] - dz2 = z - r2_pos[2] - az2_est = np.arctan2(dy2, dx2) * 180.0 / np.pi - el2_est = np.arctan2(dz2, np.sqrt(dx2**2 + dy2**2)) * 180.0 / np.pi - - return [ - range1_est - r1_meas['range'], - range2_est - r2_meas['range'], - (az1_est - r1_meas['azimuth']) * range1_est / 100.0, - (az2_est - r2_meas['azimuth']) * range2_est / 100.0, - (el1_est - r1_meas['elevation']) * range1_est / 100.0, - (el2_est - r2_meas['elevation']) * range2_est / 100.0, - ] - - x0 = (r1_pos[0] + r2_pos[0]) / 2.0 - y0 = (r1_pos[1] + r2_pos[1]) / 2.0 - z0 = 500.0 # Initial guess for altitude - - result = least_squares(residuals, [x0, y0, z0]) - return result.x - -def estimate_velocity(positions, times): - """Estimate velocity from position history using linear regression.""" - if len(positions) < 2: - return np.array([0.0, 0.0, 0.0]) - - # Use last 5 positions for velocity estimation - n = min(5, len(positions)) - recent_pos = np.array(positions[-n:]) - recent_times = np.array(times[-n:]) - - # Linear regression for each axis - velocity = np.zeros(3) - for axis in range(3): - coeffs = np.polyfit(recent_times, recent_pos[:, axis], 1) - velocity[axis] = coeffs[0] - - return velocity - -# ============================================================================= -# Main Simulation -# ============================================================================= - -print("=" * 80) -print("Trajectory Precision Analysis") -print("=" * 80) -print(f"Projectile: Mach 0.8 ({MACH_08} m/s)") -print(f"Radar baseline: {BASELINE_DISTANCE/1000:.1f} km") -print(f"Simulation duration: {SIM_DURATION}s") -print(f"Update rate: {UPDATE_RATE} Hz") -print() - -# Run simulation -times = np.arange(0, SIM_DURATION, 1.0/UPDATE_RATE) -positions_true = [] -positions_estimated = [] -velocities_estimated = [] -position_errors = [] -velocity_errors = [] - -for t in times: - # True position - true_pos = projectile_position(t) - positions_true.append(true_pos.copy()) - - # Radar measurements - r1_meas = radar_measurement(RADAR1_POS, true_pos, t, TOTAL_FIXED_LATENCY) - r2_meas = radar_measurement(RADAR2_POS, true_pos, t, TOTAL_FIXED_LATENCY) - - # Triangulate - estimated_pos = triangulate(r1_meas, r2_meas, RADAR1_POS, RADAR2_POS) - positions_estimated.append(estimated_pos) - - # Estimate velocity - estimated_vel = estimate_velocity(positions_estimated, times) - velocities_estimated.append(estimated_vel) - - # Calculate errors - pos_error = np.linalg.norm(true_pos - estimated_pos) - vel_error = np.linalg.norm(PROJECTILE_VELOCITY - estimated_vel) - - position_errors.append(pos_error) - velocity_errors.append(vel_error) - -# ============================================================================= -# Results Analysis -# ============================================================================= - -position_errors = np.array(position_errors) -velocity_errors = np.array(velocity_errors) - -print("=" * 80) -print("Position Precision") -print("=" * 80) -print(f"Mean position error: {np.mean(position_errors):.2f} m") -print(f"Median position error: {np.median(position_errors):.2f} m") -print(f"Max position error: {np.max(position_errors):.2f} m") -print(f"95th percentile: {np.percentile(position_errors, 95):.2f} m") -print() - -print("=" * 80) -print("Velocity Precision") -print("=" * 80) -print(f"Mean velocity error: {np.mean(velocity_errors):.2f} m/s") -print(f"Median velocity error: {np.median(velocity_errors):.2f} m/s") -print(f"Max velocity error: {np.max(velocity_errors):.2f} m/s") -print(f"95th percentile: {np.percentile(velocity_errors, 95):.2f} m/s") -print() - -# Trajectory prediction analysis -print("=" * 80) -print("Trajectory Prediction Accuracy") -print("=" * 80) -print("How far ahead can we predict the projectile's position?") -print() - -# Test prediction accuracy at different lead times -for lead_time in [0.5, 1.0, 2.0, 5.0]: - prediction_errors = [] - for i in range(len(times) - int(lead_time * UPDATE_RATE)): - t_now = times[i] - t_future = t_now + lead_time - - # Predict using current velocity estimate - predicted_pos = positions_estimated[i] + velocities_estimated[i] * lead_time - - # True future position - true_future_pos = projectile_position(t_future) - - error = np.linalg.norm(predicted_pos - true_future_pos) - prediction_errors.append(error) - - if prediction_errors: - print(f"Lead time {lead_time}s: Mean error = {np.mean(prediction_errors):.1f} m, " - f"95th percentile = {np.percentile(prediction_errors, 95):.1f} m") - -print() -print("=" * 80) -print("Key Insights") -print("=" * 80) -print(f"1. Position precision: ~{np.mean(position_errors):.0f}m average error") -print(f"2. Velocity precision: ~{np.mean(velocity_errors):.0f}m/s average error") -print(f"3. At Mach 0.8, projectile travels {MACH_08:.0f}m per second") -print(f"4. With 10Hz update rate, projectile moves {MACH_08/10:.0f}m between updates") -print(f"5. Position error is ~{np.mean(position_errors)/(MACH_08/10):.1f}x the inter-update distance") -print() -print("Conclusion: Two GPS-synced AERIS-10 radars can track a Mach 0.8 projectile") -print("with ~20m position accuracy and ~10m/s velocity accuracy, sufficient for") -print("most trajectory prediction and interception scenarios.") diff --git a/defense_sim_v2/.gitignore b/simulation/.gitignore similarity index 100% rename from defense_sim_v2/.gitignore rename to simulation/.gitignore diff --git a/defense_sim_v2/DEMO_USER.txt b/simulation/DEMO_USER.txt similarity index 100% rename from defense_sim_v2/DEMO_USER.txt rename to simulation/DEMO_USER.txt diff --git a/defense_sim_v2/PROJECT_SPEC.md b/simulation/PROJECT_SPEC.md similarity index 95% rename from defense_sim_v2/PROJECT_SPEC.md rename to simulation/PROJECT_SPEC.md index 6df7dae..885a80d 100644 --- a/defense_sim_v2/PROJECT_SPEC.md +++ b/simulation/PROJECT_SPEC.md @@ -1,4 +1,4 @@ -# Defense Sim V2: Project Specification +# Overwatch: Project Specification Attack-vehicle presets: `projectile_preset` selects `shahed_136`, `shahed_238`, `cruise_missile`, `ballistic_reentry`, `prop_drone`, `custom`, or uniform `random` selection. The five named profiles are built from open-source vehicle data (Wikipedia infoboxes, CSIS Missile Threat, manufacturer spec sheets, defense-press reporting); mass, reference area, and drag coefficient are per-class engineering estimates sampled once per run and documented in `simulation/presets.py`. `scenario.projectile_profile` records realized values and `scenario.projectile_preset_requested` records the selection mode. @@ -34,9 +34,9 @@ Reference finding: `georgeh1ll/Projectile-Motion-Simulator` contains `simulate_p Both drone classes use the same physical dynamics and differ only in configuration, mission/guidance policy, and sensors. Initial multirotor model: rigid body with mass, diagonal inertia (configurable), quaternion attitude, motor thrust/torque lag, rotor thrust and torque limits, gravity, translational aerodynamic drag, and moments; actuator commands pass through delay, lag, saturation, and noise before forces/moments. Position/velocity targets become bounded acceleration/attitude/thrust commands through a cascaded controller, never direct state assignments. Rate, acceleration, speed, tilt, climb/descent, and motor limits are explicit. Fixed-wing configuration may later use aerodynamic coefficients and control surfaces; it is a separate model, not a hidden approximation. -Reference finding: `riverjiang187/PyFlightSim` source has a 13-element rigid-body state (NED position, body velocity, quaternion, body rates), Newton-Euler force/moment dynamics including gravity and gyroscopic terms, quaternion kinematics, RK4, configurable aerodynamic coefficients, cascaded PID autopilot, ISA, Dryden gust shaping, and IMU/GPS/air-data/estimator modules. We adapt the separations, state representation, RK4 and quaternion approach, atmosphere, turbulence concepts, and bounded cascaded control. Its source is MIT licensed (Copyright Haiang Jiang, 2026); no code is copied in this initial implementation, so attribution is documentation only. Its model is fixed-wing oriented, has simplified diagonal inertia/aerodynamics, and must be independently checked before reuse. +Reference finding: `riverjiang187/PyFlightSim` source has a 13-element rigid-body state (NED position, body velocity, quaternion, body rates), Newton-Euler force/moment dynamics including gravity and gyroscopic terms, quaternion kinematics, RK4, configurable aerodynamic coefficients, cascaded PID autopilot, ISA, Dryden gust shaping, and IMU/GPS/air-data/estimator modules. We adapt the separations, state representation, RK4 and quaternion approach, atmosphere, turbulence concepts, and bounded cascaded control. No code is copied in this initial implementation. Its model is fixed-wing oriented, has simplified diagonal inertia/aerodynamics, and must be independently checked before reuse. -Reference finding: `nb-programmer/dronesim` source separates physics engine, actor, action/control interface, and sensors; `SimpleUAVDronePhysics` maps RC commands through velocity/altitude/yaw PID-like controls to thrust and includes operation states. Its implementation mixes centimeter-like implicit units, per-tick motion, direct angle/velocity updates and simple multiplicative drag; sensor base and IMU are mostly stubs. We adapt the command/actuator/interface separation and lifecycle ideas, not its dynamics or numeric constants. MIT license (Copyright imaprogrammer, 2022); no code is copied in this initial implementation. +Reference finding: `nb-programmer/dronesim` source separates physics engine, actor, action/control interface, and sensors; `SimpleUAVDronePhysics` maps RC commands through velocity/altitude/yaw PID-like controls to thrust and includes operation states. Its implementation mixes centimeter-like implicit units, per-tick motion, direct angle/velocity updates and simple multiplicative drag; sensor base and IMU are mostly stubs. We adapt the command/actuator/interface separation and lifecycle ideas, not its dynamics or numeric constants. No code is copied in this initial implementation. ## 7. Environment, atmosphere and turbulence @@ -100,7 +100,7 @@ Initial core is a configurable engineering approximation. ISA layering, simplifi ### Device timing and link assumptions -The AERIS-10 profile is based on repository firmware in `9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp`. With 16 chirps at PRI1=167 μs and PRI2=175 μs, a 175.4 μs guard, three phase patterns for each of 15 elevation positions, and four 1 ms stepper pulses, one azimuth frame is 258.133 ms. Fifty azimuth positions imply a 12.90665 s same-direction revisit. The model checks a 50-position azimuth sector and a 31-beam elevation fan; finite horizontal sector width (7.2° per mechanical step) and 3° elevation spacing are approximations pending measured antenna beam patterns. AERIS-10N/10X maximum range is configured as 3 km/20 km from the root README. +The AERIS-10 profile is based on repository firmware in `firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp`. With 16 chirps at PRI1=167 μs and PRI2=175 μs, a 175.4 μs guard, three phase patterns for each of 15 elevation positions, and four 1 ms stepper pulses, one azimuth frame is 258.133 ms. Fifty azimuth positions imply a 12.90665 s same-direction revisit. The model checks a 50-position azimuth sector and a 31-beam elevation fan; finite horizontal sector width (7.2° per mechanical step) and 3° elevation spacing are approximations pending measured antenna beam patterns. AERIS-10N/10X maximum range is configured as 3 km/20 km from the root README. The repository's `simulate_trajectory_precision.py` uses 10 Hz observations, 2 m range sigma, 0.5° azimuth/elevation sigma, 1 m/s Doppler sigma, and 7.1 ms fixed latency. Those values are adopted as R&D sensor/error and processing-delay assumptions, not verified AERIS-10 performance. The firmware-derived scan cadence supersedes that script's uniform 10 Hz update assumption for radar detections. diff --git a/defense_sim_v2/README.md b/simulation/README.md similarity index 85% rename from defense_sim_v2/README.md rename to simulation/README.md index 259cdd2..8c0bd92 100644 --- a/defense_sim_v2/README.md +++ b/simulation/README.md @@ -1,18 +1,24 @@ -# Defense Sim V2 +# Overwatch Real-world physics simulation with backend-owned state, dynamics, sensing, device timing, random variation, interception events, and statistics. The Vue 3 client is an operator-configuration and visualization layer. Three.js renders backend-provided state and trajectory samples; it does not calculate physics or predictions. +## Radar console + +Open **Radar List** next to **3D Simulation** for per-site scan status, central-command report freshness, counts and USB connection placeholders. Select a card or a 3D radar marker to open the Python-backed radar GUI. The console includes a range/Doppler map, A-Scope, spectrum, settings, diagnostics, recording and JSON config/data export. The standalone V6 demo and supplied synthetic I/Q replay are available without a scene. See [radar_gui_port.md](radar_gui_port.md) for sources, controls and hardware limits. + +Radar tracks now fuse noisy angles, range and radial Doppler using a gated Stone Soup EKF. Raw observations remain visible; displayed forecasts shorten with uncertainty. USB status remains disconnected until a hardware adapter is implemented. + ## Quick start ```bash -cd defense_sim_v2 +cd simulation python -m pip install -e '.[server,dev,flight,performance]' python -m defense_sim.cli --steps 500 --seed 7 ``` The backend owns a fixed simulation clock, reduced flight dynamics, noisy device observations, timestamped Stone Soup tracking, chronological swept contacts, protected-area outcomes and per-projectile Monte Carlo statistics. SciPy supplies numerical reference checks and attitude conversions. The three independent radii are the protected circle (10 km), radar site ring (12 km) and grounded defender staging ring (28 km). -By default, the first delivered radar position detection alerts all available defensive drones to climb vertically to a configurable standby altitude (150 m). The frontend exposes the altitude and an early-takeoff toggle. Standby commands use the modeled radio queue, loss, latency and up to three delivery attempts. These drones remain available for assignment. A trajectory assignment requires a usable radar-derived motion estimate. Exactly three available defenders are ranked by 3D distance to the finite estimated future path through its first protected-circle entry. A necessary reachability screen can reject a configuration; the simulation never promises successful interception. Commands and subsequent estimate updates incur the modeled radio delay before affecting motion. Prediction assumes constant velocity and uses no hidden attacker mass, drag or true wind. +Once a radar regression has a usable altitude, the one drone on the incoming side of the ring climbs toward that estimated height and holds its ring position. The line run waits until the recent samples agree on a heading, then that same drone runs the attacker's predicted track at full speed. Commands incur the modeled radio delay. Prediction assumes constant velocity and uses no hidden attacker mass, drag or true wind. The simulation never promises a successful interception. The reduced attacker integrates gravity, air-relative drag and bounded optional guidance acceleration. Guidance never overwrites physical velocity. This is an illustrative powered point-mass model, not a calibrated aircraft. Grounded idle defenders remain supported by the ground; activated reduced defenders use an explicitly identified kinematic surrogate with actuator response and speed/climb bounds. @@ -34,7 +40,7 @@ All coordinates use NED world axes (m, m/s, m/s²; altitude is negative down). P ## Device timing defaults -The AERIS-10 scan sequence derives from `9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp`: 16 chirps in each long/short train, PRI values of 167/175 μs, a 175.4 μs guard, three phase patterns at each of 15 elevation positions, four 1 ms stepper pulses, and 50 azimuth positions. The model yields about 258.133 ms per azimuth frame and 12.90665 s per full azimuth revisit. AERIS-10N and AERIS-10X range limits (3 km and 20 km) follow the repository hardware README. Range/bearing/Doppler uncertainty and the 7.1 ms fixed processing delay follow `simulate_trajectory_precision.py`; these are model inputs, not bench-validated performance claims. +The AERIS-10 scan sequence derives from `firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp`: 16 chirps in each long/short train, PRI values of 167/175 μs, a 175.4 μs guard, three phase patterns at each of 15 elevation positions, four 1 ms stepper pulses, and 50 azimuth positions. The model yields about 258.133 ms per azimuth frame and 12.90665 s per full azimuth revisit. AERIS-10N and AERIS-10X range limits (3 km and 20 km) follow the repository hardware README. Range/bearing/Doppler uncertainty and the 7.1 ms fixed processing delay are model inputs carried forward from the retired tracking study. They are not bench-validated performance claims. Drone navigation defaults to 10 Hz, flight control to 50 Hz, and actuator acceleration response to a 0.25 s time constant. The wireless drone link is an explicit, tunable R&D assumption: 20 Hz send slots, 250 kbit/s shared half-duplex channel, 64-byte telemetry and 48-byte command payloads plus 24 bytes framing, 50 ms one-way delay, 5 ms latency jitter, 10 ms command computation, and 0% packet loss. Packets are serialized, with airtime and queueing included. Radar reporting is modeled as wired with the configured 7.1 ms fixed delay. Drone-link defaults are not specifications for a selected radio and should be tuned during field R&D. diff --git a/defense_sim_v2/deploy/defense-sim-backend.service b/simulation/deploy/defense-sim-backend.service similarity index 55% rename from defense_sim_v2/deploy/defense-sim-backend.service rename to simulation/deploy/defense-sim-backend.service index a5a39f2..785f8d9 100644 --- a/defense_sim_v2/deploy/defense-sim-backend.service +++ b/simulation/deploy/defense-sim-backend.service @@ -1,16 +1,16 @@ [Unit] -Description=Defense Sim V2 Socket.IO backend +Description=Overwatch Socket.IO backend After=network-online.target Wants=network-online.target [Service] Type=simple -WorkingDirectory=/home/dre/git/plfm/defense_sim_v2 -EnvironmentFile=/home/dre/git/plfm/defense_sim_v2/deploy/auth.env.local +WorkingDirectory=/home/dre/git/plfm/simulation +EnvironmentFile=/home/dre/git/plfm/simulation/deploy/auth.env.local Environment=SIM_BIND_HOST=0.0.0.0 Environment=SIM_PORT=8000 Environment=SIM_ALLOWED_ORIGINS=https://defense.naori.cloud,http://localhost:3333,http://localhost:8088,http://127.0.0.1:8088 -ExecStart=/home/dre/git/plfm/defense_sim_v2/.venv/bin/python -m defense_sim.server.socketio_server +ExecStart=/home/dre/git/plfm/simulation/.venv/bin/python -m defense_sim.server.socketio_server Restart=on-failure RestartSec=3 diff --git a/defense_sim_v2/deploy/supabase/compose.yml b/simulation/deploy/supabase/compose.yml similarity index 100% rename from defense_sim_v2/deploy/supabase/compose.yml rename to simulation/deploy/supabase/compose.yml diff --git a/defense_sim_v2/deploy/supabase/frontend.conf b/simulation/deploy/supabase/frontend.conf similarity index 100% rename from defense_sim_v2/deploy/supabase/frontend.conf rename to simulation/deploy/supabase/frontend.conf diff --git a/defense_sim_v2/deploy/supabase/migrate.sql b/simulation/deploy/supabase/migrate.sql similarity index 100% rename from defense_sim_v2/deploy/supabase/migrate.sql rename to simulation/deploy/supabase/migrate.sql diff --git a/defense_sim_v2/deploy/supabase/roles.sql b/simulation/deploy/supabase/roles.sql similarity index 100% rename from defense_sim_v2/deploy/supabase/roles.sql rename to simulation/deploy/supabase/roles.sql diff --git a/defense_sim_v2/deploy/traefik-defense-sim-v2.yml b/simulation/deploy/traefik-defense-sim-v2.yml similarity index 100% rename from defense_sim_v2/deploy/traefik-defense-sim-v2.yml rename to simulation/deploy/traefik-defense-sim-v2.yml diff --git a/defense_sim_v2/frontend/.dockerignore b/simulation/frontend/.dockerignore similarity index 100% rename from defense_sim_v2/frontend/.dockerignore rename to simulation/frontend/.dockerignore diff --git a/defense_sim_v2/frontend/.editorconfig b/simulation/frontend/.editorconfig similarity index 100% rename from defense_sim_v2/frontend/.editorconfig rename to simulation/frontend/.editorconfig diff --git a/defense_sim_v2/frontend/.env.example b/simulation/frontend/.env.example similarity index 94% rename from defense_sim_v2/frontend/.env.example rename to simulation/frontend/.env.example index 7fc0816..29b7d45 100644 --- a/defense_sim_v2/frontend/.env.example +++ b/simulation/frontend/.env.example @@ -13,4 +13,4 @@ VITE_SIM_SOCKET_URL= VITE_ALLOWED_LOCALES= # Brand name shown in the sidebar and page titles -VITE_BRAND_NAME=Defense Sim V2 +VITE_BRAND_NAME=Overwatch diff --git a/defense_sim_v2/frontend/.github/FUNDING.yml b/simulation/frontend/.github/FUNDING.yml similarity index 100% rename from defense_sim_v2/frontend/.github/FUNDING.yml rename to simulation/frontend/.github/FUNDING.yml diff --git a/defense_sim_v2/frontend/.github/workflows/ci.yml b/simulation/frontend/.github/workflows/ci.yml similarity index 100% rename from defense_sim_v2/frontend/.github/workflows/ci.yml rename to simulation/frontend/.github/workflows/ci.yml diff --git a/defense_sim_v2/frontend/.gitignore b/simulation/frontend/.gitignore similarity index 100% rename from defense_sim_v2/frontend/.gitignore rename to simulation/frontend/.gitignore diff --git a/defense_sim_v2/frontend/.npmrc b/simulation/frontend/.npmrc similarity index 100% rename from defense_sim_v2/frontend/.npmrc rename to simulation/frontend/.npmrc diff --git a/defense_sim_v2/frontend/.vscode/extensions.json b/simulation/frontend/.vscode/extensions.json similarity index 100% rename from defense_sim_v2/frontend/.vscode/extensions.json rename to simulation/frontend/.vscode/extensions.json diff --git a/defense_sim_v2/frontend/.vscode/settings.json b/simulation/frontend/.vscode/settings.json similarity index 100% rename from defense_sim_v2/frontend/.vscode/settings.json rename to simulation/frontend/.vscode/settings.json diff --git a/defense_sim_v2/frontend/Dockerfile b/simulation/frontend/Dockerfile similarity index 100% rename from defense_sim_v2/frontend/Dockerfile rename to simulation/frontend/Dockerfile diff --git a/defense_sim_v2/frontend/README.md b/simulation/frontend/README.md similarity index 100% rename from defense_sim_v2/frontend/README.md rename to simulation/frontend/README.md diff --git a/defense_sim_v2/frontend/components.json b/simulation/frontend/components.json similarity index 100% rename from defense_sim_v2/frontend/components.json rename to simulation/frontend/components.json diff --git a/defense_sim_v2/frontend/cypress.config.ts b/simulation/frontend/cypress.config.ts similarity index 100% rename from defense_sim_v2/frontend/cypress.config.ts rename to simulation/frontend/cypress.config.ts diff --git a/defense_sim_v2/frontend/cypress/e2e/auth.spec.ts b/simulation/frontend/cypress/e2e/auth.spec.ts similarity index 100% rename from defense_sim_v2/frontend/cypress/e2e/auth.spec.ts rename to simulation/frontend/cypress/e2e/auth.spec.ts diff --git a/defense_sim_v2/frontend/cypress/e2e/basic.spec.ts b/simulation/frontend/cypress/e2e/basic.spec.ts similarity index 100% rename from defense_sim_v2/frontend/cypress/e2e/basic.spec.ts rename to simulation/frontend/cypress/e2e/basic.spec.ts diff --git a/defense_sim_v2/frontend/cypress/tsconfig.json b/simulation/frontend/cypress/tsconfig.json similarity index 100% rename from defense_sim_v2/frontend/cypress/tsconfig.json rename to simulation/frontend/cypress/tsconfig.json diff --git a/defense_sim_v2/frontend/eslint.config.js b/simulation/frontend/eslint.config.js similarity index 100% rename from defense_sim_v2/frontend/eslint.config.js rename to simulation/frontend/eslint.config.js diff --git a/defense_sim_v2/frontend/index.html b/simulation/frontend/index.html similarity index 100% rename from defense_sim_v2/frontend/index.html rename to simulation/frontend/index.html diff --git a/defense_sim_v2/frontend/locales/README.md b/simulation/frontend/locales/README.md similarity index 100% rename from defense_sim_v2/frontend/locales/README.md rename to simulation/frontend/locales/README.md diff --git a/defense_sim_v2/frontend/locales/en.yml b/simulation/frontend/locales/en.yml similarity index 100% rename from defense_sim_v2/frontend/locales/en.yml rename to simulation/frontend/locales/en.yml diff --git a/defense_sim_v2/frontend/netlify.toml b/simulation/frontend/netlify.toml similarity index 100% rename from defense_sim_v2/frontend/netlify.toml rename to simulation/frontend/netlify.toml diff --git a/defense_sim_v2/frontend/package.json b/simulation/frontend/package.json similarity index 100% rename from defense_sim_v2/frontend/package.json rename to simulation/frontend/package.json diff --git a/defense_sim_v2/frontend/pnpm-lock.yaml b/simulation/frontend/pnpm-lock.yaml similarity index 100% rename from defense_sim_v2/frontend/pnpm-lock.yaml rename to simulation/frontend/pnpm-lock.yaml diff --git a/defense_sim_v2/frontend/pnpm-workspace.yaml b/simulation/frontend/pnpm-workspace.yaml similarity index 100% rename from defense_sim_v2/frontend/pnpm-workspace.yaml rename to simulation/frontend/pnpm-workspace.yaml diff --git a/defense_sim_v2/frontend/public/_headers b/simulation/frontend/public/_headers similarity index 100% rename from defense_sim_v2/frontend/public/_headers rename to simulation/frontend/public/_headers diff --git a/defense_sim_v2/frontend/public/favicon-dark.svg b/simulation/frontend/public/favicon-dark.svg similarity index 100% rename from defense_sim_v2/frontend/public/favicon-dark.svg rename to simulation/frontend/public/favicon-dark.svg diff --git a/defense_sim_v2/frontend/public/favicon.svg b/simulation/frontend/public/favicon.svg similarity index 100% rename from defense_sim_v2/frontend/public/favicon.svg rename to simulation/frontend/public/favicon.svg diff --git a/defense_sim_v2/frontend/public/pwa-192x192.png b/simulation/frontend/public/pwa-192x192.png similarity index 100% rename from defense_sim_v2/frontend/public/pwa-192x192.png rename to simulation/frontend/public/pwa-192x192.png diff --git a/defense_sim_v2/frontend/public/pwa-512x512.png b/simulation/frontend/public/pwa-512x512.png similarity index 100% rename from defense_sim_v2/frontend/public/pwa-512x512.png rename to simulation/frontend/public/pwa-512x512.png diff --git a/defense_sim_v2/frontend/public/safari-pinned-tab.svg b/simulation/frontend/public/safari-pinned-tab.svg similarity index 100% rename from defense_sim_v2/frontend/public/safari-pinned-tab.svg rename to simulation/frontend/public/safari-pinned-tab.svg diff --git a/defense_sim_v2/frontend/src/App.vue b/simulation/frontend/src/App.vue similarity index 85% rename from defense_sim_v2/frontend/src/App.vue rename to simulation/frontend/src/App.vue index 5d08e87..8561498 100644 --- a/defense_sim_v2/frontend/src/App.vue +++ b/simulation/frontend/src/App.vue @@ -3,7 +3,7 @@ import { useHead } from '@unhead/vue' import { useDark } from '@vueuse/core' const isDark = useDark() -const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Defense Sim V2' +const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Overwatch' useHead({ titleTemplate: (title?: string) => { diff --git a/defense_sim_v2/frontend/src/auto-imports.d.ts b/simulation/frontend/src/auto-imports.d.ts similarity index 100% rename from defense_sim_v2/frontend/src/auto-imports.d.ts rename to simulation/frontend/src/auto-imports.d.ts diff --git a/defense_sim_v2/frontend/src/components.d.ts b/simulation/frontend/src/components.d.ts similarity index 99% rename from defense_sim_v2/frontend/src/components.d.ts rename to simulation/frontend/src/components.d.ts index e024e27..edcdfae 100644 --- a/defense_sim_v2/frontend/src/components.d.ts +++ b/simulation/frontend/src/components.d.ts @@ -228,6 +228,8 @@ declare module 'vue' { PopoverContent: typeof import('./components/ui/popover/PopoverContent.vue')['default'] PopoverTrigger: typeof import('./components/ui/popover/PopoverTrigger.vue')['default'] Progress: typeof import('./components/ui/progress/Progress.vue')['default'] + RadarConsolePanel: typeof import('./components/RadarConsolePanel.vue')['default'] + RadarPlot: typeof import('./components/RadarPlot.vue')['default'] RadioGroup: typeof import('./components/ui/radio-group/RadioGroup.vue')['default'] RadioGroupItem: typeof import('./components/ui/radio-group/RadioGroupItem.vue')['default'] RangeCalendar: typeof import('./components/ui/range-calendar/RangeCalendar.vue')['default'] diff --git a/defense_sim_v2/frontend/src/components/AppSidebar.vue b/simulation/frontend/src/components/AppSidebar.vue similarity index 96% rename from defense_sim_v2/frontend/src/components/AppSidebar.vue rename to simulation/frontend/src/components/AppSidebar.vue index 62784ab..efc89c8 100644 --- a/defense_sim_v2/frontend/src/components/AppSidebar.vue +++ b/simulation/frontend/src/components/AppSidebar.vue @@ -15,7 +15,7 @@ import { import DarkModeSwitcher from '~/components/DarkModeSwitcher.vue' import LanguageSwitcher from '~/components/LanguageSwitcher.vue' -const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Vitesse' +const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Overwatch' const navItems = [ { title: 'Dashboard', url: '/dashboard', icon: LayoutDashboard }, diff --git a/defense_sim_v2/frontend/src/components/DarkModeSwitcher.vue b/simulation/frontend/src/components/DarkModeSwitcher.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/DarkModeSwitcher.vue rename to simulation/frontend/src/components/DarkModeSwitcher.vue diff --git a/defense_sim_v2/frontend/src/components/LanguageSwitcher.vue b/simulation/frontend/src/components/LanguageSwitcher.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/LanguageSwitcher.vue rename to simulation/frontend/src/components/LanguageSwitcher.vue diff --git a/defense_sim_v2/frontend/src/components/README.md b/simulation/frontend/src/components/README.md similarity index 100% rename from defense_sim_v2/frontend/src/components/README.md rename to simulation/frontend/src/components/README.md diff --git a/simulation/frontend/src/components/RadarConsolePanel.vue b/simulation/frontend/src/components/RadarConsolePanel.vue new file mode 100644 index 0000000..8f4db89 --- /dev/null +++ b/simulation/frontend/src/components/RadarConsolePanel.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/simulation/frontend/src/components/RadarPlot.vue b/simulation/frontend/src/components/RadarPlot.vue new file mode 100644 index 0000000..6b0ee20 --- /dev/null +++ b/simulation/frontend/src/components/RadarPlot.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/defense_sim_v2/frontend/src/components/SimulationScene.vue b/simulation/frontend/src/components/SimulationScene.vue similarity index 51% rename from defense_sim_v2/frontend/src/components/SimulationScene.vue rename to simulation/frontend/src/components/SimulationScene.vue index f05d2d3..1ba4341 100644 --- a/defense_sim_v2/frontend/src/components/SimulationScene.vue +++ b/simulation/frontend/src/components/SimulationScene.vue @@ -1,10 +1,11 @@ diff --git a/defense_sim_v2/frontend/src/components/TheInput.vue b/simulation/frontend/src/components/TheInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/TheInput.vue rename to simulation/frontend/src/components/TheInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/accordion/Accordion.vue b/simulation/frontend/src/components/ui/accordion/Accordion.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/accordion/Accordion.vue rename to simulation/frontend/src/components/ui/accordion/Accordion.vue diff --git a/defense_sim_v2/frontend/src/components/ui/accordion/AccordionContent.vue b/simulation/frontend/src/components/ui/accordion/AccordionContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/accordion/AccordionContent.vue rename to simulation/frontend/src/components/ui/accordion/AccordionContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/accordion/AccordionItem.vue b/simulation/frontend/src/components/ui/accordion/AccordionItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/accordion/AccordionItem.vue rename to simulation/frontend/src/components/ui/accordion/AccordionItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/accordion/AccordionTrigger.vue b/simulation/frontend/src/components/ui/accordion/AccordionTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/accordion/AccordionTrigger.vue rename to simulation/frontend/src/components/ui/accordion/AccordionTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/accordion/index.ts b/simulation/frontend/src/components/ui/accordion/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/accordion/index.ts rename to simulation/frontend/src/components/ui/accordion/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialog.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialog.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialog.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialog.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogAction.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogAction.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogAction.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogAction.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogCancel.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogCancel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogCancel.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogCancel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogContent.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogContent.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogDescription.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogDescription.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogFooter.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogFooter.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogHeader.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogHeader.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogTitle.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogTitle.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogTrigger.vue b/simulation/frontend/src/components/ui/alert-dialog/AlertDialogTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/AlertDialogTrigger.vue rename to simulation/frontend/src/components/ui/alert-dialog/AlertDialogTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert-dialog/index.ts b/simulation/frontend/src/components/ui/alert-dialog/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert-dialog/index.ts rename to simulation/frontend/src/components/ui/alert-dialog/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/alert/Alert.vue b/simulation/frontend/src/components/ui/alert/Alert.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert/Alert.vue rename to simulation/frontend/src/components/ui/alert/Alert.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert/AlertDescription.vue b/simulation/frontend/src/components/ui/alert/AlertDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert/AlertDescription.vue rename to simulation/frontend/src/components/ui/alert/AlertDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert/AlertTitle.vue b/simulation/frontend/src/components/ui/alert/AlertTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert/AlertTitle.vue rename to simulation/frontend/src/components/ui/alert/AlertTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/alert/index.ts b/simulation/frontend/src/components/ui/alert/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/alert/index.ts rename to simulation/frontend/src/components/ui/alert/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/aspect-ratio/AspectRatio.vue b/simulation/frontend/src/components/ui/aspect-ratio/AspectRatio.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/aspect-ratio/AspectRatio.vue rename to simulation/frontend/src/components/ui/aspect-ratio/AspectRatio.vue diff --git a/defense_sim_v2/frontend/src/components/ui/aspect-ratio/index.ts b/simulation/frontend/src/components/ui/aspect-ratio/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/aspect-ratio/index.ts rename to simulation/frontend/src/components/ui/aspect-ratio/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/avatar/Avatar.vue b/simulation/frontend/src/components/ui/avatar/Avatar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/avatar/Avatar.vue rename to simulation/frontend/src/components/ui/avatar/Avatar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/avatar/AvatarFallback.vue b/simulation/frontend/src/components/ui/avatar/AvatarFallback.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/avatar/AvatarFallback.vue rename to simulation/frontend/src/components/ui/avatar/AvatarFallback.vue diff --git a/defense_sim_v2/frontend/src/components/ui/avatar/AvatarImage.vue b/simulation/frontend/src/components/ui/avatar/AvatarImage.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/avatar/AvatarImage.vue rename to simulation/frontend/src/components/ui/avatar/AvatarImage.vue diff --git a/defense_sim_v2/frontend/src/components/ui/avatar/index.ts b/simulation/frontend/src/components/ui/avatar/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/avatar/index.ts rename to simulation/frontend/src/components/ui/avatar/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/badge/Badge.vue b/simulation/frontend/src/components/ui/badge/Badge.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/badge/Badge.vue rename to simulation/frontend/src/components/ui/badge/Badge.vue diff --git a/defense_sim_v2/frontend/src/components/ui/badge/index.ts b/simulation/frontend/src/components/ui/badge/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/badge/index.ts rename to simulation/frontend/src/components/ui/badge/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/Breadcrumb.vue b/simulation/frontend/src/components/ui/breadcrumb/Breadcrumb.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/Breadcrumb.vue rename to simulation/frontend/src/components/ui/breadcrumb/Breadcrumb.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbItem.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbItem.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbLink.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbLink.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbLink.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbLink.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbList.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbList.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbList.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbList.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbPage.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbPage.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbPage.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbPage.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbSeparator.vue b/simulation/frontend/src/components/ui/breadcrumb/BreadcrumbSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/BreadcrumbSeparator.vue rename to simulation/frontend/src/components/ui/breadcrumb/BreadcrumbSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/breadcrumb/index.ts b/simulation/frontend/src/components/ui/breadcrumb/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/breadcrumb/index.ts rename to simulation/frontend/src/components/ui/breadcrumb/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroup.vue b/simulation/frontend/src/components/ui/button-group/ButtonGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroup.vue rename to simulation/frontend/src/components/ui/button-group/ButtonGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroupSeparator.vue b/simulation/frontend/src/components/ui/button-group/ButtonGroupSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroupSeparator.vue rename to simulation/frontend/src/components/ui/button-group/ButtonGroupSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroupText.vue b/simulation/frontend/src/components/ui/button-group/ButtonGroupText.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button-group/ButtonGroupText.vue rename to simulation/frontend/src/components/ui/button-group/ButtonGroupText.vue diff --git a/defense_sim_v2/frontend/src/components/ui/button-group/index.ts b/simulation/frontend/src/components/ui/button-group/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button-group/index.ts rename to simulation/frontend/src/components/ui/button-group/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/button/Button.vue b/simulation/frontend/src/components/ui/button/Button.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button/Button.vue rename to simulation/frontend/src/components/ui/button/Button.vue diff --git a/defense_sim_v2/frontend/src/components/ui/button/index.ts b/simulation/frontend/src/components/ui/button/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/button/index.ts rename to simulation/frontend/src/components/ui/button/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/Calendar.vue b/simulation/frontend/src/components/ui/calendar/Calendar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/Calendar.vue rename to simulation/frontend/src/components/ui/calendar/Calendar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarCell.vue b/simulation/frontend/src/components/ui/calendar/CalendarCell.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarCell.vue rename to simulation/frontend/src/components/ui/calendar/CalendarCell.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarCellTrigger.vue b/simulation/frontend/src/components/ui/calendar/CalendarCellTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarCellTrigger.vue rename to simulation/frontend/src/components/ui/calendar/CalendarCellTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarGrid.vue b/simulation/frontend/src/components/ui/calendar/CalendarGrid.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarGrid.vue rename to simulation/frontend/src/components/ui/calendar/CalendarGrid.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridBody.vue b/simulation/frontend/src/components/ui/calendar/CalendarGridBody.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridBody.vue rename to simulation/frontend/src/components/ui/calendar/CalendarGridBody.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridHead.vue b/simulation/frontend/src/components/ui/calendar/CalendarGridHead.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridHead.vue rename to simulation/frontend/src/components/ui/calendar/CalendarGridHead.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridRow.vue b/simulation/frontend/src/components/ui/calendar/CalendarGridRow.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarGridRow.vue rename to simulation/frontend/src/components/ui/calendar/CalendarGridRow.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeadCell.vue b/simulation/frontend/src/components/ui/calendar/CalendarHeadCell.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeadCell.vue rename to simulation/frontend/src/components/ui/calendar/CalendarHeadCell.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeader.vue b/simulation/frontend/src/components/ui/calendar/CalendarHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeader.vue rename to simulation/frontend/src/components/ui/calendar/CalendarHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeading.vue b/simulation/frontend/src/components/ui/calendar/CalendarHeading.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarHeading.vue rename to simulation/frontend/src/components/ui/calendar/CalendarHeading.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarNextButton.vue b/simulation/frontend/src/components/ui/calendar/CalendarNextButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarNextButton.vue rename to simulation/frontend/src/components/ui/calendar/CalendarNextButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/CalendarPrevButton.vue b/simulation/frontend/src/components/ui/calendar/CalendarPrevButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/CalendarPrevButton.vue rename to simulation/frontend/src/components/ui/calendar/CalendarPrevButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/calendar/index.ts b/simulation/frontend/src/components/ui/calendar/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/calendar/index.ts rename to simulation/frontend/src/components/ui/calendar/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/card/Card.vue b/simulation/frontend/src/components/ui/card/Card.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/Card.vue rename to simulation/frontend/src/components/ui/card/Card.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/CardContent.vue b/simulation/frontend/src/components/ui/card/CardContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/CardContent.vue rename to simulation/frontend/src/components/ui/card/CardContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/CardDescription.vue b/simulation/frontend/src/components/ui/card/CardDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/CardDescription.vue rename to simulation/frontend/src/components/ui/card/CardDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/CardFooter.vue b/simulation/frontend/src/components/ui/card/CardFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/CardFooter.vue rename to simulation/frontend/src/components/ui/card/CardFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/CardHeader.vue b/simulation/frontend/src/components/ui/card/CardHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/CardHeader.vue rename to simulation/frontend/src/components/ui/card/CardHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/CardTitle.vue b/simulation/frontend/src/components/ui/card/CardTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/CardTitle.vue rename to simulation/frontend/src/components/ui/card/CardTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/card/index.ts b/simulation/frontend/src/components/ui/card/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/card/index.ts rename to simulation/frontend/src/components/ui/card/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/Carousel.vue b/simulation/frontend/src/components/ui/carousel/Carousel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/Carousel.vue rename to simulation/frontend/src/components/ui/carousel/Carousel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/CarouselContent.vue b/simulation/frontend/src/components/ui/carousel/CarouselContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/CarouselContent.vue rename to simulation/frontend/src/components/ui/carousel/CarouselContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/CarouselItem.vue b/simulation/frontend/src/components/ui/carousel/CarouselItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/CarouselItem.vue rename to simulation/frontend/src/components/ui/carousel/CarouselItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/CarouselNext.vue b/simulation/frontend/src/components/ui/carousel/CarouselNext.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/CarouselNext.vue rename to simulation/frontend/src/components/ui/carousel/CarouselNext.vue diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/CarouselPrevious.vue b/simulation/frontend/src/components/ui/carousel/CarouselPrevious.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/CarouselPrevious.vue rename to simulation/frontend/src/components/ui/carousel/CarouselPrevious.vue diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/index.ts b/simulation/frontend/src/components/ui/carousel/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/index.ts rename to simulation/frontend/src/components/ui/carousel/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/interface.ts b/simulation/frontend/src/components/ui/carousel/interface.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/interface.ts rename to simulation/frontend/src/components/ui/carousel/interface.ts diff --git a/defense_sim_v2/frontend/src/components/ui/carousel/useCarousel.ts b/simulation/frontend/src/components/ui/carousel/useCarousel.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/carousel/useCarousel.ts rename to simulation/frontend/src/components/ui/carousel/useCarousel.ts diff --git a/defense_sim_v2/frontend/src/components/ui/chart/ChartCrosshair.vue b/simulation/frontend/src/components/ui/chart/ChartCrosshair.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/ChartCrosshair.vue rename to simulation/frontend/src/components/ui/chart/ChartCrosshair.vue diff --git a/defense_sim_v2/frontend/src/components/ui/chart/ChartLegend.vue b/simulation/frontend/src/components/ui/chart/ChartLegend.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/ChartLegend.vue rename to simulation/frontend/src/components/ui/chart/ChartLegend.vue diff --git a/defense_sim_v2/frontend/src/components/ui/chart/ChartSingleTooltip.vue b/simulation/frontend/src/components/ui/chart/ChartSingleTooltip.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/ChartSingleTooltip.vue rename to simulation/frontend/src/components/ui/chart/ChartSingleTooltip.vue diff --git a/defense_sim_v2/frontend/src/components/ui/chart/ChartTooltip.vue b/simulation/frontend/src/components/ui/chart/ChartTooltip.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/ChartTooltip.vue rename to simulation/frontend/src/components/ui/chart/ChartTooltip.vue diff --git a/defense_sim_v2/frontend/src/components/ui/chart/index.ts b/simulation/frontend/src/components/ui/chart/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/index.ts rename to simulation/frontend/src/components/ui/chart/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/chart/interface.ts b/simulation/frontend/src/components/ui/chart/interface.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/interface.ts rename to simulation/frontend/src/components/ui/chart/interface.ts diff --git a/defense_sim_v2/frontend/src/components/ui/chart/mountChartTooltip.ts b/simulation/frontend/src/components/ui/chart/mountChartTooltip.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/chart/mountChartTooltip.ts rename to simulation/frontend/src/components/ui/chart/mountChartTooltip.ts diff --git a/defense_sim_v2/frontend/src/components/ui/checkbox/Checkbox.vue b/simulation/frontend/src/components/ui/checkbox/Checkbox.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/checkbox/Checkbox.vue rename to simulation/frontend/src/components/ui/checkbox/Checkbox.vue diff --git a/defense_sim_v2/frontend/src/components/ui/checkbox/index.ts b/simulation/frontend/src/components/ui/checkbox/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/checkbox/index.ts rename to simulation/frontend/src/components/ui/checkbox/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/collapsible/Collapsible.vue b/simulation/frontend/src/components/ui/collapsible/Collapsible.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/collapsible/Collapsible.vue rename to simulation/frontend/src/components/ui/collapsible/Collapsible.vue diff --git a/defense_sim_v2/frontend/src/components/ui/collapsible/CollapsibleContent.vue b/simulation/frontend/src/components/ui/collapsible/CollapsibleContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/collapsible/CollapsibleContent.vue rename to simulation/frontend/src/components/ui/collapsible/CollapsibleContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/collapsible/CollapsibleTrigger.vue b/simulation/frontend/src/components/ui/collapsible/CollapsibleTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/collapsible/CollapsibleTrigger.vue rename to simulation/frontend/src/components/ui/collapsible/CollapsibleTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/collapsible/index.ts b/simulation/frontend/src/components/ui/collapsible/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/collapsible/index.ts rename to simulation/frontend/src/components/ui/collapsible/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/Combobox.vue b/simulation/frontend/src/components/ui/combobox/Combobox.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/Combobox.vue rename to simulation/frontend/src/components/ui/combobox/Combobox.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxAnchor.vue b/simulation/frontend/src/components/ui/combobox/ComboboxAnchor.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxAnchor.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxAnchor.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxEmpty.vue b/simulation/frontend/src/components/ui/combobox/ComboboxEmpty.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxEmpty.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxEmpty.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxGroup.vue b/simulation/frontend/src/components/ui/combobox/ComboboxGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxGroup.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxInput.vue b/simulation/frontend/src/components/ui/combobox/ComboboxInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxInput.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxItem.vue b/simulation/frontend/src/components/ui/combobox/ComboboxItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxItem.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxList.vue b/simulation/frontend/src/components/ui/combobox/ComboboxList.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxList.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxList.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxSeparator.vue b/simulation/frontend/src/components/ui/combobox/ComboboxSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxSeparator.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/ComboboxTrigger.vue b/simulation/frontend/src/components/ui/combobox/ComboboxTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/ComboboxTrigger.vue rename to simulation/frontend/src/components/ui/combobox/ComboboxTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/combobox/index.ts b/simulation/frontend/src/components/ui/combobox/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/combobox/index.ts rename to simulation/frontend/src/components/ui/combobox/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/command/Command.vue b/simulation/frontend/src/components/ui/command/Command.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/Command.vue rename to simulation/frontend/src/components/ui/command/Command.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandDialog.vue b/simulation/frontend/src/components/ui/command/CommandDialog.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandDialog.vue rename to simulation/frontend/src/components/ui/command/CommandDialog.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandEmpty.vue b/simulation/frontend/src/components/ui/command/CommandEmpty.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandEmpty.vue rename to simulation/frontend/src/components/ui/command/CommandEmpty.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandGroup.vue b/simulation/frontend/src/components/ui/command/CommandGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandGroup.vue rename to simulation/frontend/src/components/ui/command/CommandGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandInput.vue b/simulation/frontend/src/components/ui/command/CommandInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandInput.vue rename to simulation/frontend/src/components/ui/command/CommandInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandItem.vue b/simulation/frontend/src/components/ui/command/CommandItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandItem.vue rename to simulation/frontend/src/components/ui/command/CommandItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandList.vue b/simulation/frontend/src/components/ui/command/CommandList.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandList.vue rename to simulation/frontend/src/components/ui/command/CommandList.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandSeparator.vue b/simulation/frontend/src/components/ui/command/CommandSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandSeparator.vue rename to simulation/frontend/src/components/ui/command/CommandSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/CommandShortcut.vue b/simulation/frontend/src/components/ui/command/CommandShortcut.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/CommandShortcut.vue rename to simulation/frontend/src/components/ui/command/CommandShortcut.vue diff --git a/defense_sim_v2/frontend/src/components/ui/command/index.ts b/simulation/frontend/src/components/ui/command/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/command/index.ts rename to simulation/frontend/src/components/ui/command/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenu.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenu.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenu.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenu.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuCheckboxItem.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuCheckboxItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuCheckboxItem.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuCheckboxItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuContent.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuContent.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuGroup.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuGroup.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuItem.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuItem.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuLabel.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuLabel.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuPortal.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuPortal.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuPortal.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuPortal.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuRadioGroup.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuRadioGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuRadioGroup.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuRadioGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuRadioItem.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuRadioItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuRadioItem.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuRadioItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSeparator.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSeparator.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuShortcut.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuShortcut.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuShortcut.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuShortcut.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSub.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuSub.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSub.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuSub.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSubContent.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuSubContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSubContent.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuSubContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSubTrigger.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuSubTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuSubTrigger.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuSubTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuTrigger.vue b/simulation/frontend/src/components/ui/context-menu/ContextMenuTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/ContextMenuTrigger.vue rename to simulation/frontend/src/components/ui/context-menu/ContextMenuTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/context-menu/index.ts b/simulation/frontend/src/components/ui/context-menu/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/context-menu/index.ts rename to simulation/frontend/src/components/ui/context-menu/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/Dialog.vue b/simulation/frontend/src/components/ui/dialog/Dialog.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/Dialog.vue rename to simulation/frontend/src/components/ui/dialog/Dialog.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogClose.vue b/simulation/frontend/src/components/ui/dialog/DialogClose.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogClose.vue rename to simulation/frontend/src/components/ui/dialog/DialogClose.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogContent.vue b/simulation/frontend/src/components/ui/dialog/DialogContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogContent.vue rename to simulation/frontend/src/components/ui/dialog/DialogContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogDescription.vue b/simulation/frontend/src/components/ui/dialog/DialogDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogDescription.vue rename to simulation/frontend/src/components/ui/dialog/DialogDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogFooter.vue b/simulation/frontend/src/components/ui/dialog/DialogFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogFooter.vue rename to simulation/frontend/src/components/ui/dialog/DialogFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogHeader.vue b/simulation/frontend/src/components/ui/dialog/DialogHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogHeader.vue rename to simulation/frontend/src/components/ui/dialog/DialogHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogScrollContent.vue b/simulation/frontend/src/components/ui/dialog/DialogScrollContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogScrollContent.vue rename to simulation/frontend/src/components/ui/dialog/DialogScrollContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogTitle.vue b/simulation/frontend/src/components/ui/dialog/DialogTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogTitle.vue rename to simulation/frontend/src/components/ui/dialog/DialogTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/DialogTrigger.vue b/simulation/frontend/src/components/ui/dialog/DialogTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/DialogTrigger.vue rename to simulation/frontend/src/components/ui/dialog/DialogTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dialog/index.ts b/simulation/frontend/src/components/ui/dialog/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dialog/index.ts rename to simulation/frontend/src/components/ui/dialog/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/Drawer.vue b/simulation/frontend/src/components/ui/drawer/Drawer.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/Drawer.vue rename to simulation/frontend/src/components/ui/drawer/Drawer.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerContent.vue b/simulation/frontend/src/components/ui/drawer/DrawerContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerContent.vue rename to simulation/frontend/src/components/ui/drawer/DrawerContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerDescription.vue b/simulation/frontend/src/components/ui/drawer/DrawerDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerDescription.vue rename to simulation/frontend/src/components/ui/drawer/DrawerDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerFooter.vue b/simulation/frontend/src/components/ui/drawer/DrawerFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerFooter.vue rename to simulation/frontend/src/components/ui/drawer/DrawerFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerHeader.vue b/simulation/frontend/src/components/ui/drawer/DrawerHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerHeader.vue rename to simulation/frontend/src/components/ui/drawer/DrawerHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerOverlay.vue b/simulation/frontend/src/components/ui/drawer/DrawerOverlay.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerOverlay.vue rename to simulation/frontend/src/components/ui/drawer/DrawerOverlay.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/DrawerTitle.vue b/simulation/frontend/src/components/ui/drawer/DrawerTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/DrawerTitle.vue rename to simulation/frontend/src/components/ui/drawer/DrawerTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/drawer/index.ts b/simulation/frontend/src/components/ui/drawer/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/drawer/index.ts rename to simulation/frontend/src/components/ui/drawer/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenu.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenu.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenu.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenu.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuContent.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuContent.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuGroup.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuGroup.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuItem.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuItem.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuLabel.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuLabel.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSub.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSub.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSub.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSub.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue b/simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue rename to simulation/frontend/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/dropdown-menu/index.ts b/simulation/frontend/src/components/ui/dropdown-menu/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/dropdown-menu/index.ts rename to simulation/frontend/src/components/ui/dropdown-menu/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/empty/Empty.vue b/simulation/frontend/src/components/ui/empty/Empty.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/Empty.vue rename to simulation/frontend/src/components/ui/empty/Empty.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/EmptyContent.vue b/simulation/frontend/src/components/ui/empty/EmptyContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/EmptyContent.vue rename to simulation/frontend/src/components/ui/empty/EmptyContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/EmptyDescription.vue b/simulation/frontend/src/components/ui/empty/EmptyDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/EmptyDescription.vue rename to simulation/frontend/src/components/ui/empty/EmptyDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/EmptyHeader.vue b/simulation/frontend/src/components/ui/empty/EmptyHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/EmptyHeader.vue rename to simulation/frontend/src/components/ui/empty/EmptyHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/EmptyMedia.vue b/simulation/frontend/src/components/ui/empty/EmptyMedia.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/EmptyMedia.vue rename to simulation/frontend/src/components/ui/empty/EmptyMedia.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/EmptyTitle.vue b/simulation/frontend/src/components/ui/empty/EmptyTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/EmptyTitle.vue rename to simulation/frontend/src/components/ui/empty/EmptyTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/empty/index.ts b/simulation/frontend/src/components/ui/empty/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/empty/index.ts rename to simulation/frontend/src/components/ui/empty/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/field/Field.vue b/simulation/frontend/src/components/ui/field/Field.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/Field.vue rename to simulation/frontend/src/components/ui/field/Field.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldContent.vue b/simulation/frontend/src/components/ui/field/FieldContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldContent.vue rename to simulation/frontend/src/components/ui/field/FieldContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldDescription.vue b/simulation/frontend/src/components/ui/field/FieldDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldDescription.vue rename to simulation/frontend/src/components/ui/field/FieldDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldError.vue b/simulation/frontend/src/components/ui/field/FieldError.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldError.vue rename to simulation/frontend/src/components/ui/field/FieldError.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldGroup.vue b/simulation/frontend/src/components/ui/field/FieldGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldGroup.vue rename to simulation/frontend/src/components/ui/field/FieldGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldLabel.vue b/simulation/frontend/src/components/ui/field/FieldLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldLabel.vue rename to simulation/frontend/src/components/ui/field/FieldLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldLegend.vue b/simulation/frontend/src/components/ui/field/FieldLegend.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldLegend.vue rename to simulation/frontend/src/components/ui/field/FieldLegend.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldSeparator.vue b/simulation/frontend/src/components/ui/field/FieldSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldSeparator.vue rename to simulation/frontend/src/components/ui/field/FieldSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldSet.vue b/simulation/frontend/src/components/ui/field/FieldSet.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldSet.vue rename to simulation/frontend/src/components/ui/field/FieldSet.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/FieldTitle.vue b/simulation/frontend/src/components/ui/field/FieldTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/FieldTitle.vue rename to simulation/frontend/src/components/ui/field/FieldTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/field/index.ts b/simulation/frontend/src/components/ui/field/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/field/index.ts rename to simulation/frontend/src/components/ui/field/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/form/FormControl.vue b/simulation/frontend/src/components/ui/form/FormControl.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/FormControl.vue rename to simulation/frontend/src/components/ui/form/FormControl.vue diff --git a/defense_sim_v2/frontend/src/components/ui/form/FormDescription.vue b/simulation/frontend/src/components/ui/form/FormDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/FormDescription.vue rename to simulation/frontend/src/components/ui/form/FormDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/form/FormItem.vue b/simulation/frontend/src/components/ui/form/FormItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/FormItem.vue rename to simulation/frontend/src/components/ui/form/FormItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/form/FormLabel.vue b/simulation/frontend/src/components/ui/form/FormLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/FormLabel.vue rename to simulation/frontend/src/components/ui/form/FormLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/form/FormMessage.vue b/simulation/frontend/src/components/ui/form/FormMessage.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/FormMessage.vue rename to simulation/frontend/src/components/ui/form/FormMessage.vue diff --git a/defense_sim_v2/frontend/src/components/ui/form/index.ts b/simulation/frontend/src/components/ui/form/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/index.ts rename to simulation/frontend/src/components/ui/form/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/form/injectionKeys.ts b/simulation/frontend/src/components/ui/form/injectionKeys.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/injectionKeys.ts rename to simulation/frontend/src/components/ui/form/injectionKeys.ts diff --git a/defense_sim_v2/frontend/src/components/ui/form/useFormField.ts b/simulation/frontend/src/components/ui/form/useFormField.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/form/useFormField.ts rename to simulation/frontend/src/components/ui/form/useFormField.ts diff --git a/defense_sim_v2/frontend/src/components/ui/hover-card/HoverCard.vue b/simulation/frontend/src/components/ui/hover-card/HoverCard.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/hover-card/HoverCard.vue rename to simulation/frontend/src/components/ui/hover-card/HoverCard.vue diff --git a/defense_sim_v2/frontend/src/components/ui/hover-card/HoverCardContent.vue b/simulation/frontend/src/components/ui/hover-card/HoverCardContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/hover-card/HoverCardContent.vue rename to simulation/frontend/src/components/ui/hover-card/HoverCardContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/hover-card/HoverCardTrigger.vue b/simulation/frontend/src/components/ui/hover-card/HoverCardTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/hover-card/HoverCardTrigger.vue rename to simulation/frontend/src/components/ui/hover-card/HoverCardTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/hover-card/index.ts b/simulation/frontend/src/components/ui/hover-card/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/hover-card/index.ts rename to simulation/frontend/src/components/ui/hover-card/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroup.vue b/simulation/frontend/src/components/ui/input-group/InputGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroup.vue rename to simulation/frontend/src/components/ui/input-group/InputGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroupAddon.vue b/simulation/frontend/src/components/ui/input-group/InputGroupAddon.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroupAddon.vue rename to simulation/frontend/src/components/ui/input-group/InputGroupAddon.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroupButton.vue b/simulation/frontend/src/components/ui/input-group/InputGroupButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroupButton.vue rename to simulation/frontend/src/components/ui/input-group/InputGroupButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroupInput.vue b/simulation/frontend/src/components/ui/input-group/InputGroupInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroupInput.vue rename to simulation/frontend/src/components/ui/input-group/InputGroupInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroupText.vue b/simulation/frontend/src/components/ui/input-group/InputGroupText.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroupText.vue rename to simulation/frontend/src/components/ui/input-group/InputGroupText.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/InputGroupTextarea.vue b/simulation/frontend/src/components/ui/input-group/InputGroupTextarea.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/InputGroupTextarea.vue rename to simulation/frontend/src/components/ui/input-group/InputGroupTextarea.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input-group/index.ts b/simulation/frontend/src/components/ui/input-group/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input-group/index.ts rename to simulation/frontend/src/components/ui/input-group/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/input/Input.vue b/simulation/frontend/src/components/ui/input/Input.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input/Input.vue rename to simulation/frontend/src/components/ui/input/Input.vue diff --git a/defense_sim_v2/frontend/src/components/ui/input/index.ts b/simulation/frontend/src/components/ui/input/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/input/index.ts rename to simulation/frontend/src/components/ui/input/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/item/Item.vue b/simulation/frontend/src/components/ui/item/Item.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/Item.vue rename to simulation/frontend/src/components/ui/item/Item.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemActions.vue b/simulation/frontend/src/components/ui/item/ItemActions.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemActions.vue rename to simulation/frontend/src/components/ui/item/ItemActions.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemContent.vue b/simulation/frontend/src/components/ui/item/ItemContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemContent.vue rename to simulation/frontend/src/components/ui/item/ItemContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemDescription.vue b/simulation/frontend/src/components/ui/item/ItemDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemDescription.vue rename to simulation/frontend/src/components/ui/item/ItemDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemFooter.vue b/simulation/frontend/src/components/ui/item/ItemFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemFooter.vue rename to simulation/frontend/src/components/ui/item/ItemFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemGroup.vue b/simulation/frontend/src/components/ui/item/ItemGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemGroup.vue rename to simulation/frontend/src/components/ui/item/ItemGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemHeader.vue b/simulation/frontend/src/components/ui/item/ItemHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemHeader.vue rename to simulation/frontend/src/components/ui/item/ItemHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemMedia.vue b/simulation/frontend/src/components/ui/item/ItemMedia.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemMedia.vue rename to simulation/frontend/src/components/ui/item/ItemMedia.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemSeparator.vue b/simulation/frontend/src/components/ui/item/ItemSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemSeparator.vue rename to simulation/frontend/src/components/ui/item/ItemSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/ItemTitle.vue b/simulation/frontend/src/components/ui/item/ItemTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/ItemTitle.vue rename to simulation/frontend/src/components/ui/item/ItemTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/item/index.ts b/simulation/frontend/src/components/ui/item/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/item/index.ts rename to simulation/frontend/src/components/ui/item/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/kbd/Kbd.vue b/simulation/frontend/src/components/ui/kbd/Kbd.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/kbd/Kbd.vue rename to simulation/frontend/src/components/ui/kbd/Kbd.vue diff --git a/defense_sim_v2/frontend/src/components/ui/kbd/KbdGroup.vue b/simulation/frontend/src/components/ui/kbd/KbdGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/kbd/KbdGroup.vue rename to simulation/frontend/src/components/ui/kbd/KbdGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/kbd/index.ts b/simulation/frontend/src/components/ui/kbd/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/kbd/index.ts rename to simulation/frontend/src/components/ui/kbd/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/label/Label.vue b/simulation/frontend/src/components/ui/label/Label.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/label/Label.vue rename to simulation/frontend/src/components/ui/label/Label.vue diff --git a/defense_sim_v2/frontend/src/components/ui/label/index.ts b/simulation/frontend/src/components/ui/label/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/label/index.ts rename to simulation/frontend/src/components/ui/label/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/Menubar.vue b/simulation/frontend/src/components/ui/menubar/Menubar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/Menubar.vue rename to simulation/frontend/src/components/ui/menubar/Menubar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarCheckboxItem.vue b/simulation/frontend/src/components/ui/menubar/MenubarCheckboxItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarCheckboxItem.vue rename to simulation/frontend/src/components/ui/menubar/MenubarCheckboxItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarContent.vue b/simulation/frontend/src/components/ui/menubar/MenubarContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarContent.vue rename to simulation/frontend/src/components/ui/menubar/MenubarContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarGroup.vue b/simulation/frontend/src/components/ui/menubar/MenubarGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarGroup.vue rename to simulation/frontend/src/components/ui/menubar/MenubarGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarItem.vue b/simulation/frontend/src/components/ui/menubar/MenubarItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarItem.vue rename to simulation/frontend/src/components/ui/menubar/MenubarItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarLabel.vue b/simulation/frontend/src/components/ui/menubar/MenubarLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarLabel.vue rename to simulation/frontend/src/components/ui/menubar/MenubarLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarMenu.vue b/simulation/frontend/src/components/ui/menubar/MenubarMenu.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarMenu.vue rename to simulation/frontend/src/components/ui/menubar/MenubarMenu.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarRadioGroup.vue b/simulation/frontend/src/components/ui/menubar/MenubarRadioGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarRadioGroup.vue rename to simulation/frontend/src/components/ui/menubar/MenubarRadioGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarRadioItem.vue b/simulation/frontend/src/components/ui/menubar/MenubarRadioItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarRadioItem.vue rename to simulation/frontend/src/components/ui/menubar/MenubarRadioItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarSeparator.vue b/simulation/frontend/src/components/ui/menubar/MenubarSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarSeparator.vue rename to simulation/frontend/src/components/ui/menubar/MenubarSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarShortcut.vue b/simulation/frontend/src/components/ui/menubar/MenubarShortcut.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarShortcut.vue rename to simulation/frontend/src/components/ui/menubar/MenubarShortcut.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarSub.vue b/simulation/frontend/src/components/ui/menubar/MenubarSub.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarSub.vue rename to simulation/frontend/src/components/ui/menubar/MenubarSub.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarSubContent.vue b/simulation/frontend/src/components/ui/menubar/MenubarSubContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarSubContent.vue rename to simulation/frontend/src/components/ui/menubar/MenubarSubContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarSubTrigger.vue b/simulation/frontend/src/components/ui/menubar/MenubarSubTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarSubTrigger.vue rename to simulation/frontend/src/components/ui/menubar/MenubarSubTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/MenubarTrigger.vue b/simulation/frontend/src/components/ui/menubar/MenubarTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/MenubarTrigger.vue rename to simulation/frontend/src/components/ui/menubar/MenubarTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/menubar/index.ts b/simulation/frontend/src/components/ui/menubar/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/menubar/index.ts rename to simulation/frontend/src/components/ui/menubar/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenu.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenu.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenu.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenu.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuContent.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuContent.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuIndicator.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuIndicator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuIndicator.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuIndicator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuItem.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuItem.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuLink.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuLink.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuLink.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuLink.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuList.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuList.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuList.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuList.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuTrigger.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuTrigger.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuViewport.vue b/simulation/frontend/src/components/ui/navigation-menu/NavigationMenuViewport.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/NavigationMenuViewport.vue rename to simulation/frontend/src/components/ui/navigation-menu/NavigationMenuViewport.vue diff --git a/defense_sim_v2/frontend/src/components/ui/navigation-menu/index.ts b/simulation/frontend/src/components/ui/navigation-menu/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/navigation-menu/index.ts rename to simulation/frontend/src/components/ui/navigation-menu/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/NumberField.vue b/simulation/frontend/src/components/ui/number-field/NumberField.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/NumberField.vue rename to simulation/frontend/src/components/ui/number-field/NumberField.vue diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldContent.vue b/simulation/frontend/src/components/ui/number-field/NumberFieldContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldContent.vue rename to simulation/frontend/src/components/ui/number-field/NumberFieldContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldDecrement.vue b/simulation/frontend/src/components/ui/number-field/NumberFieldDecrement.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldDecrement.vue rename to simulation/frontend/src/components/ui/number-field/NumberFieldDecrement.vue diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldIncrement.vue b/simulation/frontend/src/components/ui/number-field/NumberFieldIncrement.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldIncrement.vue rename to simulation/frontend/src/components/ui/number-field/NumberFieldIncrement.vue diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldInput.vue b/simulation/frontend/src/components/ui/number-field/NumberFieldInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/NumberFieldInput.vue rename to simulation/frontend/src/components/ui/number-field/NumberFieldInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/number-field/index.ts b/simulation/frontend/src/components/ui/number-field/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/number-field/index.ts rename to simulation/frontend/src/components/ui/number-field/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/Pagination.vue b/simulation/frontend/src/components/ui/pagination/Pagination.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/Pagination.vue rename to simulation/frontend/src/components/ui/pagination/Pagination.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationContent.vue b/simulation/frontend/src/components/ui/pagination/PaginationContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationContent.vue rename to simulation/frontend/src/components/ui/pagination/PaginationContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationEllipsis.vue b/simulation/frontend/src/components/ui/pagination/PaginationEllipsis.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationEllipsis.vue rename to simulation/frontend/src/components/ui/pagination/PaginationEllipsis.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationFirst.vue b/simulation/frontend/src/components/ui/pagination/PaginationFirst.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationFirst.vue rename to simulation/frontend/src/components/ui/pagination/PaginationFirst.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationItem.vue b/simulation/frontend/src/components/ui/pagination/PaginationItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationItem.vue rename to simulation/frontend/src/components/ui/pagination/PaginationItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationLast.vue b/simulation/frontend/src/components/ui/pagination/PaginationLast.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationLast.vue rename to simulation/frontend/src/components/ui/pagination/PaginationLast.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationNext.vue b/simulation/frontend/src/components/ui/pagination/PaginationNext.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationNext.vue rename to simulation/frontend/src/components/ui/pagination/PaginationNext.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/PaginationPrevious.vue b/simulation/frontend/src/components/ui/pagination/PaginationPrevious.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/PaginationPrevious.vue rename to simulation/frontend/src/components/ui/pagination/PaginationPrevious.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pagination/index.ts b/simulation/frontend/src/components/ui/pagination/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pagination/index.ts rename to simulation/frontend/src/components/ui/pagination/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/pin-input/PinInput.vue b/simulation/frontend/src/components/ui/pin-input/PinInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pin-input/PinInput.vue rename to simulation/frontend/src/components/ui/pin-input/PinInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pin-input/PinInputGroup.vue b/simulation/frontend/src/components/ui/pin-input/PinInputGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pin-input/PinInputGroup.vue rename to simulation/frontend/src/components/ui/pin-input/PinInputGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pin-input/PinInputSeparator.vue b/simulation/frontend/src/components/ui/pin-input/PinInputSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pin-input/PinInputSeparator.vue rename to simulation/frontend/src/components/ui/pin-input/PinInputSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pin-input/PinInputSlot.vue b/simulation/frontend/src/components/ui/pin-input/PinInputSlot.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pin-input/PinInputSlot.vue rename to simulation/frontend/src/components/ui/pin-input/PinInputSlot.vue diff --git a/defense_sim_v2/frontend/src/components/ui/pin-input/index.ts b/simulation/frontend/src/components/ui/pin-input/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/pin-input/index.ts rename to simulation/frontend/src/components/ui/pin-input/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/popover/Popover.vue b/simulation/frontend/src/components/ui/popover/Popover.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/popover/Popover.vue rename to simulation/frontend/src/components/ui/popover/Popover.vue diff --git a/defense_sim_v2/frontend/src/components/ui/popover/PopoverContent.vue b/simulation/frontend/src/components/ui/popover/PopoverContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/popover/PopoverContent.vue rename to simulation/frontend/src/components/ui/popover/PopoverContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/popover/PopoverTrigger.vue b/simulation/frontend/src/components/ui/popover/PopoverTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/popover/PopoverTrigger.vue rename to simulation/frontend/src/components/ui/popover/PopoverTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/popover/index.ts b/simulation/frontend/src/components/ui/popover/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/popover/index.ts rename to simulation/frontend/src/components/ui/popover/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/progress/Progress.vue b/simulation/frontend/src/components/ui/progress/Progress.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/progress/Progress.vue rename to simulation/frontend/src/components/ui/progress/Progress.vue diff --git a/defense_sim_v2/frontend/src/components/ui/progress/index.ts b/simulation/frontend/src/components/ui/progress/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/progress/index.ts rename to simulation/frontend/src/components/ui/progress/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/radio-group/RadioGroup.vue b/simulation/frontend/src/components/ui/radio-group/RadioGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/radio-group/RadioGroup.vue rename to simulation/frontend/src/components/ui/radio-group/RadioGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/radio-group/RadioGroupItem.vue b/simulation/frontend/src/components/ui/radio-group/RadioGroupItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/radio-group/RadioGroupItem.vue rename to simulation/frontend/src/components/ui/radio-group/RadioGroupItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/radio-group/index.ts b/simulation/frontend/src/components/ui/radio-group/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/radio-group/index.ts rename to simulation/frontend/src/components/ui/radio-group/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendar.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendar.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarCell.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarCell.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarCell.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarCell.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarCellTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGrid.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarGrid.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGrid.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarGrid.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridBody.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridBody.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridBody.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridBody.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridHead.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridHead.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridHead.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridHead.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridRow.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridRow.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarGridRow.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarGridRow.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeadCell.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeadCell.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeadCell.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeadCell.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeader.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeader.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeading.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeading.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarHeading.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarHeading.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarNextButton.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarNextButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarNextButton.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarNextButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarPrevButton.vue b/simulation/frontend/src/components/ui/range-calendar/RangeCalendarPrevButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/RangeCalendarPrevButton.vue rename to simulation/frontend/src/components/ui/range-calendar/RangeCalendarPrevButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/range-calendar/index.ts b/simulation/frontend/src/components/ui/range-calendar/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/range-calendar/index.ts rename to simulation/frontend/src/components/ui/range-calendar/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/resizable/ResizableHandle.vue b/simulation/frontend/src/components/ui/resizable/ResizableHandle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/resizable/ResizableHandle.vue rename to simulation/frontend/src/components/ui/resizable/ResizableHandle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/resizable/ResizablePanelGroup.vue b/simulation/frontend/src/components/ui/resizable/ResizablePanelGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/resizable/ResizablePanelGroup.vue rename to simulation/frontend/src/components/ui/resizable/ResizablePanelGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/resizable/index.ts b/simulation/frontend/src/components/ui/resizable/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/resizable/index.ts rename to simulation/frontend/src/components/ui/resizable/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/scroll-area/ScrollArea.vue b/simulation/frontend/src/components/ui/scroll-area/ScrollArea.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/scroll-area/ScrollArea.vue rename to simulation/frontend/src/components/ui/scroll-area/ScrollArea.vue diff --git a/defense_sim_v2/frontend/src/components/ui/scroll-area/ScrollBar.vue b/simulation/frontend/src/components/ui/scroll-area/ScrollBar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/scroll-area/ScrollBar.vue rename to simulation/frontend/src/components/ui/scroll-area/ScrollBar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/scroll-area/index.ts b/simulation/frontend/src/components/ui/scroll-area/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/scroll-area/index.ts rename to simulation/frontend/src/components/ui/scroll-area/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/select/Select.vue b/simulation/frontend/src/components/ui/select/Select.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/Select.vue rename to simulation/frontend/src/components/ui/select/Select.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectContent.vue b/simulation/frontend/src/components/ui/select/SelectContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectContent.vue rename to simulation/frontend/src/components/ui/select/SelectContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectGroup.vue b/simulation/frontend/src/components/ui/select/SelectGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectGroup.vue rename to simulation/frontend/src/components/ui/select/SelectGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectItem.vue b/simulation/frontend/src/components/ui/select/SelectItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectItem.vue rename to simulation/frontend/src/components/ui/select/SelectItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectItemText.vue b/simulation/frontend/src/components/ui/select/SelectItemText.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectItemText.vue rename to simulation/frontend/src/components/ui/select/SelectItemText.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectLabel.vue b/simulation/frontend/src/components/ui/select/SelectLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectLabel.vue rename to simulation/frontend/src/components/ui/select/SelectLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectScrollDownButton.vue b/simulation/frontend/src/components/ui/select/SelectScrollDownButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectScrollDownButton.vue rename to simulation/frontend/src/components/ui/select/SelectScrollDownButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectScrollUpButton.vue b/simulation/frontend/src/components/ui/select/SelectScrollUpButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectScrollUpButton.vue rename to simulation/frontend/src/components/ui/select/SelectScrollUpButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectSeparator.vue b/simulation/frontend/src/components/ui/select/SelectSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectSeparator.vue rename to simulation/frontend/src/components/ui/select/SelectSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectTrigger.vue b/simulation/frontend/src/components/ui/select/SelectTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectTrigger.vue rename to simulation/frontend/src/components/ui/select/SelectTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/SelectValue.vue b/simulation/frontend/src/components/ui/select/SelectValue.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/SelectValue.vue rename to simulation/frontend/src/components/ui/select/SelectValue.vue diff --git a/defense_sim_v2/frontend/src/components/ui/select/index.ts b/simulation/frontend/src/components/ui/select/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/select/index.ts rename to simulation/frontend/src/components/ui/select/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/separator/Separator.vue b/simulation/frontend/src/components/ui/separator/Separator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/separator/Separator.vue rename to simulation/frontend/src/components/ui/separator/Separator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/separator/index.ts b/simulation/frontend/src/components/ui/separator/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/separator/index.ts rename to simulation/frontend/src/components/ui/separator/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/Sheet.vue b/simulation/frontend/src/components/ui/sheet/Sheet.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/Sheet.vue rename to simulation/frontend/src/components/ui/sheet/Sheet.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetClose.vue b/simulation/frontend/src/components/ui/sheet/SheetClose.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetClose.vue rename to simulation/frontend/src/components/ui/sheet/SheetClose.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetContent.vue b/simulation/frontend/src/components/ui/sheet/SheetContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetContent.vue rename to simulation/frontend/src/components/ui/sheet/SheetContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetDescription.vue b/simulation/frontend/src/components/ui/sheet/SheetDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetDescription.vue rename to simulation/frontend/src/components/ui/sheet/SheetDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetFooter.vue b/simulation/frontend/src/components/ui/sheet/SheetFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetFooter.vue rename to simulation/frontend/src/components/ui/sheet/SheetFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetHeader.vue b/simulation/frontend/src/components/ui/sheet/SheetHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetHeader.vue rename to simulation/frontend/src/components/ui/sheet/SheetHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetTitle.vue b/simulation/frontend/src/components/ui/sheet/SheetTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetTitle.vue rename to simulation/frontend/src/components/ui/sheet/SheetTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/SheetTrigger.vue b/simulation/frontend/src/components/ui/sheet/SheetTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/SheetTrigger.vue rename to simulation/frontend/src/components/ui/sheet/SheetTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sheet/index.ts b/simulation/frontend/src/components/ui/sheet/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sheet/index.ts rename to simulation/frontend/src/components/ui/sheet/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/Sidebar.vue b/simulation/frontend/src/components/ui/sidebar/Sidebar.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/Sidebar.vue rename to simulation/frontend/src/components/ui/sidebar/Sidebar.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarContent.vue b/simulation/frontend/src/components/ui/sidebar/SidebarContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarContent.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarFooter.vue b/simulation/frontend/src/components/ui/sidebar/SidebarFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarFooter.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroup.vue b/simulation/frontend/src/components/ui/sidebar/SidebarGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroup.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupAction.vue b/simulation/frontend/src/components/ui/sidebar/SidebarGroupAction.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupAction.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarGroupAction.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupContent.vue b/simulation/frontend/src/components/ui/sidebar/SidebarGroupContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupContent.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarGroupContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupLabel.vue b/simulation/frontend/src/components/ui/sidebar/SidebarGroupLabel.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarGroupLabel.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarGroupLabel.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarHeader.vue b/simulation/frontend/src/components/ui/sidebar/SidebarHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarHeader.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarInput.vue b/simulation/frontend/src/components/ui/sidebar/SidebarInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarInput.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarInset.vue b/simulation/frontend/src/components/ui/sidebar/SidebarInset.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarInset.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarInset.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenu.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenu.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenu.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenu.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuAction.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuAction.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuAction.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuAction.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuBadge.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuBadge.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuBadge.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuBadge.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuButton.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuButton.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuButtonChild.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuButtonChild.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuButtonChild.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuButtonChild.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuItem.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuItem.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSkeleton.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuSkeleton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSkeleton.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuSkeleton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSub.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuSub.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSub.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuSub.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSubButton.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuSubButton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSubButton.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuSubButton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSubItem.vue b/simulation/frontend/src/components/ui/sidebar/SidebarMenuSubItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarMenuSubItem.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarMenuSubItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarProvider.vue b/simulation/frontend/src/components/ui/sidebar/SidebarProvider.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarProvider.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarProvider.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarRail.vue b/simulation/frontend/src/components/ui/sidebar/SidebarRail.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarRail.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarRail.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarSeparator.vue b/simulation/frontend/src/components/ui/sidebar/SidebarSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarSeparator.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/SidebarTrigger.vue b/simulation/frontend/src/components/ui/sidebar/SidebarTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/SidebarTrigger.vue rename to simulation/frontend/src/components/ui/sidebar/SidebarTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/index.ts b/simulation/frontend/src/components/ui/sidebar/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/index.ts rename to simulation/frontend/src/components/ui/sidebar/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/sidebar/utils.ts b/simulation/frontend/src/components/ui/sidebar/utils.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sidebar/utils.ts rename to simulation/frontend/src/components/ui/sidebar/utils.ts diff --git a/defense_sim_v2/frontend/src/components/ui/skeleton/Skeleton.vue b/simulation/frontend/src/components/ui/skeleton/Skeleton.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/skeleton/Skeleton.vue rename to simulation/frontend/src/components/ui/skeleton/Skeleton.vue diff --git a/defense_sim_v2/frontend/src/components/ui/skeleton/index.ts b/simulation/frontend/src/components/ui/skeleton/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/skeleton/index.ts rename to simulation/frontend/src/components/ui/skeleton/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/slider/Slider.vue b/simulation/frontend/src/components/ui/slider/Slider.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/slider/Slider.vue rename to simulation/frontend/src/components/ui/slider/Slider.vue diff --git a/defense_sim_v2/frontend/src/components/ui/slider/index.ts b/simulation/frontend/src/components/ui/slider/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/slider/index.ts rename to simulation/frontend/src/components/ui/slider/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/sonner/Sonner.vue b/simulation/frontend/src/components/ui/sonner/Sonner.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sonner/Sonner.vue rename to simulation/frontend/src/components/ui/sonner/Sonner.vue diff --git a/defense_sim_v2/frontend/src/components/ui/sonner/index.ts b/simulation/frontend/src/components/ui/sonner/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/sonner/index.ts rename to simulation/frontend/src/components/ui/sonner/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/spinner/Spinner.vue b/simulation/frontend/src/components/ui/spinner/Spinner.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/spinner/Spinner.vue rename to simulation/frontend/src/components/ui/spinner/Spinner.vue diff --git a/defense_sim_v2/frontend/src/components/ui/spinner/index.ts b/simulation/frontend/src/components/ui/spinner/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/spinner/index.ts rename to simulation/frontend/src/components/ui/spinner/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/Stepper.vue b/simulation/frontend/src/components/ui/stepper/Stepper.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/Stepper.vue rename to simulation/frontend/src/components/ui/stepper/Stepper.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperDescription.vue b/simulation/frontend/src/components/ui/stepper/StepperDescription.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperDescription.vue rename to simulation/frontend/src/components/ui/stepper/StepperDescription.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperIndicator.vue b/simulation/frontend/src/components/ui/stepper/StepperIndicator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperIndicator.vue rename to simulation/frontend/src/components/ui/stepper/StepperIndicator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperItem.vue b/simulation/frontend/src/components/ui/stepper/StepperItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperItem.vue rename to simulation/frontend/src/components/ui/stepper/StepperItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperSeparator.vue b/simulation/frontend/src/components/ui/stepper/StepperSeparator.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperSeparator.vue rename to simulation/frontend/src/components/ui/stepper/StepperSeparator.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperTitle.vue b/simulation/frontend/src/components/ui/stepper/StepperTitle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperTitle.vue rename to simulation/frontend/src/components/ui/stepper/StepperTitle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/StepperTrigger.vue b/simulation/frontend/src/components/ui/stepper/StepperTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/StepperTrigger.vue rename to simulation/frontend/src/components/ui/stepper/StepperTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/stepper/index.ts b/simulation/frontend/src/components/ui/stepper/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/stepper/index.ts rename to simulation/frontend/src/components/ui/stepper/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/switch/Switch.vue b/simulation/frontend/src/components/ui/switch/Switch.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/switch/Switch.vue rename to simulation/frontend/src/components/ui/switch/Switch.vue diff --git a/defense_sim_v2/frontend/src/components/ui/switch/index.ts b/simulation/frontend/src/components/ui/switch/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/switch/index.ts rename to simulation/frontend/src/components/ui/switch/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/table/Table.vue b/simulation/frontend/src/components/ui/table/Table.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/Table.vue rename to simulation/frontend/src/components/ui/table/Table.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableBody.vue b/simulation/frontend/src/components/ui/table/TableBody.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableBody.vue rename to simulation/frontend/src/components/ui/table/TableBody.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableCaption.vue b/simulation/frontend/src/components/ui/table/TableCaption.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableCaption.vue rename to simulation/frontend/src/components/ui/table/TableCaption.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableCell.vue b/simulation/frontend/src/components/ui/table/TableCell.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableCell.vue rename to simulation/frontend/src/components/ui/table/TableCell.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableEmpty.vue b/simulation/frontend/src/components/ui/table/TableEmpty.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableEmpty.vue rename to simulation/frontend/src/components/ui/table/TableEmpty.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableFooter.vue b/simulation/frontend/src/components/ui/table/TableFooter.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableFooter.vue rename to simulation/frontend/src/components/ui/table/TableFooter.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableHead.vue b/simulation/frontend/src/components/ui/table/TableHead.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableHead.vue rename to simulation/frontend/src/components/ui/table/TableHead.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableHeader.vue b/simulation/frontend/src/components/ui/table/TableHeader.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableHeader.vue rename to simulation/frontend/src/components/ui/table/TableHeader.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/TableRow.vue b/simulation/frontend/src/components/ui/table/TableRow.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/TableRow.vue rename to simulation/frontend/src/components/ui/table/TableRow.vue diff --git a/defense_sim_v2/frontend/src/components/ui/table/index.ts b/simulation/frontend/src/components/ui/table/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/table/index.ts rename to simulation/frontend/src/components/ui/table/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/tabs/Tabs.vue b/simulation/frontend/src/components/ui/tabs/Tabs.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tabs/Tabs.vue rename to simulation/frontend/src/components/ui/tabs/Tabs.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tabs/TabsContent.vue b/simulation/frontend/src/components/ui/tabs/TabsContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tabs/TabsContent.vue rename to simulation/frontend/src/components/ui/tabs/TabsContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tabs/TabsList.vue b/simulation/frontend/src/components/ui/tabs/TabsList.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tabs/TabsList.vue rename to simulation/frontend/src/components/ui/tabs/TabsList.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tabs/TabsTrigger.vue b/simulation/frontend/src/components/ui/tabs/TabsTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tabs/TabsTrigger.vue rename to simulation/frontend/src/components/ui/tabs/TabsTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tabs/index.ts b/simulation/frontend/src/components/ui/tabs/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tabs/index.ts rename to simulation/frontend/src/components/ui/tabs/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/TagsInput.vue b/simulation/frontend/src/components/ui/tags-input/TagsInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/TagsInput.vue rename to simulation/frontend/src/components/ui/tags-input/TagsInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputInput.vue b/simulation/frontend/src/components/ui/tags-input/TagsInputInput.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputInput.vue rename to simulation/frontend/src/components/ui/tags-input/TagsInputInput.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItem.vue b/simulation/frontend/src/components/ui/tags-input/TagsInputItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItem.vue rename to simulation/frontend/src/components/ui/tags-input/TagsInputItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItemDelete.vue b/simulation/frontend/src/components/ui/tags-input/TagsInputItemDelete.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItemDelete.vue rename to simulation/frontend/src/components/ui/tags-input/TagsInputItemDelete.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItemText.vue b/simulation/frontend/src/components/ui/tags-input/TagsInputItemText.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/TagsInputItemText.vue rename to simulation/frontend/src/components/ui/tags-input/TagsInputItemText.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tags-input/index.ts b/simulation/frontend/src/components/ui/tags-input/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tags-input/index.ts rename to simulation/frontend/src/components/ui/tags-input/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/textarea/Textarea.vue b/simulation/frontend/src/components/ui/textarea/Textarea.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/textarea/Textarea.vue rename to simulation/frontend/src/components/ui/textarea/Textarea.vue diff --git a/defense_sim_v2/frontend/src/components/ui/textarea/index.ts b/simulation/frontend/src/components/ui/textarea/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/textarea/index.ts rename to simulation/frontend/src/components/ui/textarea/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/toggle-group/ToggleGroup.vue b/simulation/frontend/src/components/ui/toggle-group/ToggleGroup.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/toggle-group/ToggleGroup.vue rename to simulation/frontend/src/components/ui/toggle-group/ToggleGroup.vue diff --git a/defense_sim_v2/frontend/src/components/ui/toggle-group/ToggleGroupItem.vue b/simulation/frontend/src/components/ui/toggle-group/ToggleGroupItem.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/toggle-group/ToggleGroupItem.vue rename to simulation/frontend/src/components/ui/toggle-group/ToggleGroupItem.vue diff --git a/defense_sim_v2/frontend/src/components/ui/toggle-group/index.ts b/simulation/frontend/src/components/ui/toggle-group/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/toggle-group/index.ts rename to simulation/frontend/src/components/ui/toggle-group/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/toggle/Toggle.vue b/simulation/frontend/src/components/ui/toggle/Toggle.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/toggle/Toggle.vue rename to simulation/frontend/src/components/ui/toggle/Toggle.vue diff --git a/defense_sim_v2/frontend/src/components/ui/toggle/index.ts b/simulation/frontend/src/components/ui/toggle/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/toggle/index.ts rename to simulation/frontend/src/components/ui/toggle/index.ts diff --git a/defense_sim_v2/frontend/src/components/ui/tooltip/Tooltip.vue b/simulation/frontend/src/components/ui/tooltip/Tooltip.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tooltip/Tooltip.vue rename to simulation/frontend/src/components/ui/tooltip/Tooltip.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tooltip/TooltipContent.vue b/simulation/frontend/src/components/ui/tooltip/TooltipContent.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tooltip/TooltipContent.vue rename to simulation/frontend/src/components/ui/tooltip/TooltipContent.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tooltip/TooltipProvider.vue b/simulation/frontend/src/components/ui/tooltip/TooltipProvider.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tooltip/TooltipProvider.vue rename to simulation/frontend/src/components/ui/tooltip/TooltipProvider.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tooltip/TooltipTrigger.vue b/simulation/frontend/src/components/ui/tooltip/TooltipTrigger.vue similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tooltip/TooltipTrigger.vue rename to simulation/frontend/src/components/ui/tooltip/TooltipTrigger.vue diff --git a/defense_sim_v2/frontend/src/components/ui/tooltip/index.ts b/simulation/frontend/src/components/ui/tooltip/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/components/ui/tooltip/index.ts rename to simulation/frontend/src/components/ui/tooltip/index.ts diff --git a/defense_sim_v2/frontend/src/composables/dark.ts b/simulation/frontend/src/composables/dark.ts similarity index 100% rename from defense_sim_v2/frontend/src/composables/dark.ts rename to simulation/frontend/src/composables/dark.ts diff --git a/defense_sim_v2/frontend/src/composables/useAuth.ts b/simulation/frontend/src/composables/useAuth.ts similarity index 100% rename from defense_sim_v2/frontend/src/composables/useAuth.ts rename to simulation/frontend/src/composables/useAuth.ts diff --git a/defense_sim_v2/frontend/src/composables/useLogout.ts b/simulation/frontend/src/composables/useLogout.ts similarity index 100% rename from defense_sim_v2/frontend/src/composables/useLogout.ts rename to simulation/frontend/src/composables/useLogout.ts diff --git a/defense_sim_v2/frontend/src/composables/useSimulationSocket.ts b/simulation/frontend/src/composables/useSimulationSocket.ts similarity index 60% rename from defense_sim_v2/frontend/src/composables/useSimulationSocket.ts rename to simulation/frontend/src/composables/useSimulationSocket.ts index 57006ee..fcb5ba7 100644 --- a/defense_sim_v2/frontend/src/composables/useSimulationSocket.ts +++ b/simulation/frontend/src/composables/useSimulationSocket.ts @@ -1,5 +1,5 @@ import type { Socket } from 'socket.io-client' -import type { SimulationEvent, SimulationState } from '~/types/simulation' +import type { RadarConsoleState, SimulationEvent, SimulationState } from '~/types/simulation' import { io } from 'socket.io-client' import { onMounted, onUnmounted, ref, shallowRef } from 'vue' import { supabase } from '~/lib/supabaseClient' @@ -38,8 +38,8 @@ interface SimulationOptions { ascent_k_per_m: number ascent_curve: string ascent_distance_m: number | null - early_takeoff_enabled: boolean - standby_altitude_m: number + flare_distance_m: number + interceptor_blast_radius_m: number } export function useSimulationSocket() { @@ -48,7 +48,30 @@ export function useSimulationSocket() { const connected = ref(false) const running = ref(false) const error = ref('') + const radarState = shallowRef(null) + const radarError = ref('') let socket: Socket | undefined + let selectedRadar: { id: string, mode: string } | null = null + let latestState: SimulationState | null = null + let frameQueued = false + + function showState(packet: SimulationState) { + // Drawing the scene is heavier than reading a packet. Keep the newest + // picture and paint it on the next frame, so a slow frame cannot pile + // packets up and stall the simulation clock. + latestState = packet + if (frameQueued) + return + frameQueued = true + requestAnimationFrame(() => { + frameQueued = false + const current = latestState + if (!current) + return + state.value = current + events.value = (current.events ?? []).slice(-250) + }) + } onMounted(() => { const url = import.meta.env.VITE_SIM_SOCKET_URL @@ -77,18 +100,13 @@ export function useSimulationSocket() { connected.value = false error.value = cause.message }) - socket.on('simulation_state', (packet: SimulationState) => { - state.value = packet - events.value = (packet.events ?? []).slice(-250) - }) + socket.on('simulation_state', showState) socket.on('simulation_started', () => { running.value = true }) socket.on('simulation_completed', (payload: { final_state?: SimulationState }) => { - if (payload.final_state) { - state.value = payload.final_state - events.value = (payload.final_state.events ?? []).slice(-250) - } + if (payload.final_state) + showState(payload.final_state) running.value = false }) socket.on('simulation_stopped', () => { @@ -98,6 +116,21 @@ export function useSimulationSocket() { error.value = payload.message || 'Simulation backend error' running.value = false }) + socket.on('radar_console_state', (packet: RadarConsoleState) => { + if (packet.radar_id === selectedRadar?.id && packet.mode === selectedRadar.mode) + radarState.value = packet + }) + socket.on('radar_console_error', (payload: { message?: string }) => { + radarError.value = payload.message || 'Radar console error' + }) + socket.on('radar_console_export', (payload: unknown) => { + const url = URL.createObjectURL(new Blob([JSON.stringify(payload)], { type: 'application/json' })) + const link = document.createElement('a') + link.href = url + link.download = `radar-${radarState.value?.radar_id ?? 'data'}-${Date.now()}.json` + link.click() + setTimeout(() => URL.revokeObjectURL(url), 1000) + }) }) onUnmounted(() => socket?.disconnect()) @@ -120,5 +153,22 @@ export function useSimulationSocket() { void sendCommand('simulation_stop') } - return { state, events, connected, running, error, start, stop } + function openRadar(radar_id: string, mode: string) { + selectedRadar = { id: radar_id, mode } + radarState.value = null + radarError.value = '' + void sendCommand('radar_console_open', { radar_id, mode }) + } + + function closeRadar() { + selectedRadar = null + void sendCommand('radar_console_close') + } + + function radarCommand(command: { action: string, settings?: Record }) { + radarError.value = '' + void sendCommand('radar_console_command', command) + } + + return { state, events, connected, running, error, start, stop, radarState, radarError, openRadar, closeRadar, radarCommand } } diff --git a/defense_sim_v2/frontend/src/config.ts b/simulation/frontend/src/config.ts similarity index 95% rename from defense_sim_v2/frontend/src/config.ts rename to simulation/frontend/src/config.ts index d47a6d5..bebd8ea 100644 --- a/defense_sim_v2/frontend/src/config.ts +++ b/simulation/frontend/src/config.ts @@ -1,6 +1,6 @@ const TRAILING_SLASH_RE = /\/$/ -export const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Defense Sim V2' +export const BRAND_NAME = import.meta.env.VITE_BRAND_NAME || 'Overwatch' export const VERSION = import.meta.env.VITE_APP_VERSION || 'dev' interface AppConfig { diff --git a/defense_sim_v2/frontend/src/devtools/I18nAudit.vue b/simulation/frontend/src/devtools/I18nAudit.vue similarity index 100% rename from defense_sim_v2/frontend/src/devtools/I18nAudit.vue rename to simulation/frontend/src/devtools/I18nAudit.vue diff --git a/defense_sim_v2/frontend/src/devtools/useI18nAudit.ts b/simulation/frontend/src/devtools/useI18nAudit.ts similarity index 100% rename from defense_sim_v2/frontend/src/devtools/useI18nAudit.ts rename to simulation/frontend/src/devtools/useI18nAudit.ts diff --git a/defense_sim_v2/frontend/src/layouts/404.vue b/simulation/frontend/src/layouts/404.vue similarity index 100% rename from defense_sim_v2/frontend/src/layouts/404.vue rename to simulation/frontend/src/layouts/404.vue diff --git a/defense_sim_v2/frontend/src/layouts/README.md b/simulation/frontend/src/layouts/README.md similarity index 100% rename from defense_sim_v2/frontend/src/layouts/README.md rename to simulation/frontend/src/layouts/README.md diff --git a/defense_sim_v2/frontend/src/layouts/default.vue b/simulation/frontend/src/layouts/default.vue similarity index 100% rename from defense_sim_v2/frontend/src/layouts/default.vue rename to simulation/frontend/src/layouts/default.vue diff --git a/defense_sim_v2/frontend/src/layouts/login.vue b/simulation/frontend/src/layouts/login.vue similarity index 100% rename from defense_sim_v2/frontend/src/layouts/login.vue rename to simulation/frontend/src/layouts/login.vue diff --git a/defense_sim_v2/frontend/src/layouts/with-sidebar.vue b/simulation/frontend/src/layouts/with-sidebar.vue similarity index 100% rename from defense_sim_v2/frontend/src/layouts/with-sidebar.vue rename to simulation/frontend/src/layouts/with-sidebar.vue diff --git a/defense_sim_v2/frontend/src/lib/auth/authErrorHandler.ts b/simulation/frontend/src/lib/auth/authErrorHandler.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/auth/authErrorHandler.ts rename to simulation/frontend/src/lib/auth/authErrorHandler.ts diff --git a/defense_sim_v2/frontend/src/lib/auth/authReservedPaths.ts b/simulation/frontend/src/lib/auth/authReservedPaths.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/auth/authReservedPaths.ts rename to simulation/frontend/src/lib/auth/authReservedPaths.ts diff --git a/defense_sim_v2/frontend/src/lib/auth/inviteRedirect.ts b/simulation/frontend/src/lib/auth/inviteRedirect.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/auth/inviteRedirect.ts rename to simulation/frontend/src/lib/auth/inviteRedirect.ts diff --git a/defense_sim_v2/frontend/src/lib/i18n-audit/index.ts b/simulation/frontend/src/lib/i18n-audit/index.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/i18n-audit/index.ts rename to simulation/frontend/src/lib/i18n-audit/index.ts diff --git a/defense_sim_v2/frontend/src/lib/i18n-audit/lmstudio.ts b/simulation/frontend/src/lib/i18n-audit/lmstudio.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/i18n-audit/lmstudio.ts rename to simulation/frontend/src/lib/i18n-audit/lmstudio.ts diff --git a/defense_sim_v2/frontend/src/lib/i18n-audit/scanner.ts b/simulation/frontend/src/lib/i18n-audit/scanner.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/i18n-audit/scanner.ts rename to simulation/frontend/src/lib/i18n-audit/scanner.ts diff --git a/defense_sim_v2/frontend/src/lib/simulationRuns.ts b/simulation/frontend/src/lib/simulationRuns.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/simulationRuns.ts rename to simulation/frontend/src/lib/simulationRuns.ts diff --git a/defense_sim_v2/frontend/src/lib/supabaseClient.ts b/simulation/frontend/src/lib/supabaseClient.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/supabaseClient.ts rename to simulation/frontend/src/lib/supabaseClient.ts diff --git a/defense_sim_v2/frontend/src/lib/ui-locale-prefs.ts b/simulation/frontend/src/lib/ui-locale-prefs.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/ui-locale-prefs.ts rename to simulation/frontend/src/lib/ui-locale-prefs.ts diff --git a/defense_sim_v2/frontend/src/lib/utils.ts b/simulation/frontend/src/lib/utils.ts similarity index 100% rename from defense_sim_v2/frontend/src/lib/utils.ts rename to simulation/frontend/src/lib/utils.ts diff --git a/defense_sim_v2/frontend/src/main.ts b/simulation/frontend/src/main.ts similarity index 100% rename from defense_sim_v2/frontend/src/main.ts rename to simulation/frontend/src/main.ts diff --git a/defense_sim_v2/frontend/src/modules/README.md b/simulation/frontend/src/modules/README.md similarity index 100% rename from defense_sim_v2/frontend/src/modules/README.md rename to simulation/frontend/src/modules/README.md diff --git a/defense_sim_v2/frontend/src/modules/auth.ts b/simulation/frontend/src/modules/auth.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/auth.ts rename to simulation/frontend/src/modules/auth.ts diff --git a/defense_sim_v2/frontend/src/modules/dev-i18n-audit.ts b/simulation/frontend/src/modules/dev-i18n-audit.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/dev-i18n-audit.ts rename to simulation/frontend/src/modules/dev-i18n-audit.ts diff --git a/defense_sim_v2/frontend/src/modules/i18n.ts b/simulation/frontend/src/modules/i18n.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/i18n.ts rename to simulation/frontend/src/modules/i18n.ts diff --git a/defense_sim_v2/frontend/src/modules/nprogress.ts b/simulation/frontend/src/modules/nprogress.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/nprogress.ts rename to simulation/frontend/src/modules/nprogress.ts diff --git a/defense_sim_v2/frontend/src/modules/pinia.ts b/simulation/frontend/src/modules/pinia.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/pinia.ts rename to simulation/frontend/src/modules/pinia.ts diff --git a/defense_sim_v2/frontend/src/modules/pwa.ts b/simulation/frontend/src/modules/pwa.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/pwa.ts rename to simulation/frontend/src/modules/pwa.ts diff --git a/defense_sim_v2/frontend/src/modules/router-auth.ts b/simulation/frontend/src/modules/router-auth.ts similarity index 100% rename from defense_sim_v2/frontend/src/modules/router-auth.ts rename to simulation/frontend/src/modules/router-auth.ts diff --git a/defense_sim_v2/frontend/src/pages/README.md b/simulation/frontend/src/pages/README.md similarity index 100% rename from defense_sim_v2/frontend/src/pages/README.md rename to simulation/frontend/src/pages/README.md diff --git a/defense_sim_v2/frontend/src/pages/[...all].vue b/simulation/frontend/src/pages/[...all].vue similarity index 100% rename from defense_sim_v2/frontend/src/pages/[...all].vue rename to simulation/frontend/src/pages/[...all].vue diff --git a/defense_sim_v2/frontend/src/pages/index.vue b/simulation/frontend/src/pages/index.vue similarity index 76% rename from defense_sim_v2/frontend/src/pages/index.vue rename to simulation/frontend/src/pages/index.vue index cee3500..fe85c73 100644 --- a/defense_sim_v2/frontend/src/pages/index.vue +++ b/simulation/frontend/src/pages/index.vue @@ -7,13 +7,15 @@ meta: import { Activity, Database, PanelLeftClose, PanelLeftOpen, Radio, Save, Square, Wifi, WifiOff } from 'lucide-vue-next' import { computed, nextTick, ref, shallowRef, watch } from 'vue' import SimulationScene from '~/components/SimulationScene.vue' +import RadarConsolePanel from '~/components/RadarConsolePanel.vue' +import type { RadarSiteStatus } from '~/types/simulation' import { useSimulationSocket } from '~/composables/useSimulationSocket' import { saveSimulationSnapshot } from '~/lib/simulationRuns' import { useLogout } from '~/composables/useLogout' -const { state, events, connected, running, error, start, stop } = useSimulationSocket() +const { state, events, connected, running, error, start, stop, radarState, radarError, openRadar, closeRadar, radarCommand } = useSimulationSocket() const { logout } = useLogout() -const config = ref({ projectile_preset: 'random', approach_range_km: 35, entry_speed_m_s: 150, entry_altitude_m: 1500, defense_drone_count: 24, protected_radius_km: 10, radar_radius_km: 12, drone_radius_km: 28, terminal_guidance_enabled: true, terminal_thrust_m_s2: 45, guidance_command_rate_hz: 10, wind_speed_m_s: 4, wind_direction_deg: 270, radar_model: 'aeris_10x', radar_station_count: 8, drone_link_update_rate_hz: 20, drone_link_one_way_latency_ms: 50, drone_link_latency_jitter_ms: 5, drone_link_bitrate_kbps: 250, drone_link_packet_loss_percent: 0, drone_link_compute_latency_ms: 10, drone_nav_update_rate_hz: 10, drone_nav_position_sigma_m: 2, drone_nav_velocity_sigma_m_s: 0.4, drone_control_rate_hz: 50, drone_actuator_time_constant_s: 0.25, drone_max_speed_m_s: 25, drone_dynamics: 'reduced', attacker_dynamics: 'reduced', aircraft_model: 'c172p', ascent_k_per_m: 0.002, ascent_curve: 'quintic', ascent_distance_m: 1000, ascent_automatic: true, early_takeoff_enabled: true, standby_altitude_m: 150 }) +const config = ref({ projectile_preset: 'shahed_238', approach_range_km: 35, entry_speed_m_s: 150, entry_altitude_m: 1500, defense_drone_count: 24, protected_radius_km: 10, radar_radius_km: 12, drone_radius_km: 12, terminal_guidance_enabled: true, terminal_thrust_m_s2: 45, guidance_command_rate_hz: 10, wind_speed_m_s: 4, wind_direction_deg: 270, radar_model: 'aeris_10x', radar_station_count: 8, drone_link_update_rate_hz: 20, drone_link_one_way_latency_ms: 50, drone_link_latency_jitter_ms: 5, drone_link_bitrate_kbps: 250, drone_link_packet_loss_percent: 0, drone_link_compute_latency_ms: 10, drone_nav_update_rate_hz: 10, drone_nav_position_sigma_m: 2, drone_nav_velocity_sigma_m_s: 0.4, drone_control_rate_hz: 50, drone_actuator_time_constant_s: 0.25, drone_max_speed_m_s: 25, drone_dynamics: 'reduced', attacker_dynamics: 'reduced', aircraft_model: 'c172p', ascent_k_per_m: 0.002, ascent_curve: 'quintic', ascent_distance_m: 1000, ascent_automatic: true, flare_distance_m: 1000, interceptor_blast_radius_m: 3 }) watch(() => config.value.drone_dynamics, (value) => { if (value === 'rotorpy_crazyflie') config.value.drone_max_speed_m_s = Math.min(config.value.drone_max_speed_m_s, 10) }) @@ -29,10 +31,28 @@ const saving = ref(false) const sidebarOpen = ref(true) const viewTabs = [ { id: 'scene', label: '3D SIMULATION' }, + { id: 'radar', label: 'RADAR LIST' }, { id: 'telemetry', label: 'ENTITY TELEMETRY' }, { id: 'events', label: 'SYSTEM LOG' }, ] as const const activeView = ref<(typeof viewTabs)[number]['id']>('scene') +const selectedRadarId = ref(null) +const selectedRadarMode = ref('scene') +const radarSites = computed(() => (state.value?.devices?.radars ?? []) as RadarSiteStatus[]) +function inspectRadar(id: string, mode = id === 'lab' ? 'demo' : 'scene') { + selectedRadarId.value = id + selectedRadarMode.value = mode + if (activeView.value === 'radar') openRadar(id, mode) + else activeView.value = 'radar' +} +function radarList() { + selectedRadarId.value = null + closeRadar() +} +watch(activeView, (view, previous) => { + if (view === 'radar' && selectedRadarId.value) openRadar(selectedRadarId.value, selectedRadarMode.value) + else if (previous === 'radar') closeRadar() +}) function navigateTabs(event: KeyboardEvent) { const index = viewTabs.findIndex(tab => tab.id === activeView.value) let next = index @@ -63,6 +83,23 @@ const drones = computed(() => entities.value.filter(entity => entity.type === 'd const projectiles = computed(() => entities.value.filter(entity => entity.type === 'projectile')) const activeDefenders = computed(() => drones.value.filter(drone => drone.activated_for).length) const airborneDefenders = computed(() => drones.value.filter(drone => drone.active && drone.position_ned_m[2] < -1).length) +const blastRadiusM = computed(() => { + const live = state.value?.scenario?.interceptor_blast_radius_m + return typeof live === 'number' ? live : config.value.interceptor_blast_radius_m +}) +const trackedThreat = computed(() => projectiles.value.find(entity => entity.active && entity.evaluated_speed_m_s != null) ?? projectiles.value.find(entity => entity.active)) +const engagement = computed(() => { + const row = state.value?.statistics?.engagement as { result?: string, miss_distance_m?: number, blast_radius_m?: number } | null | undefined + return row && typeof row === 'object' ? row : null +}) +const engagementText = computed(() => { + const row = engagement.value + if (!row?.result || typeof row.miss_distance_m !== 'number') + return '—' + if (row.result === 'intercepted') + return `DESTROYED ${num(row.miss_distance_m, 1)} m` + return `MISSED ${num(row.miss_distance_m, 1)} m` +}) const environment = computed(() => state.value?.environment ?? {}) const radarProfile = computed(() => state.value?.devices?.radar_profile as Record | undefined) const observations = computed(() => Object.entries(state.value?.observations ?? {})) @@ -139,7 +176,7 @@ function num(value: unknown, digits = 1) { return typeof value === 'number' && Number.isFinite(value) ? value.toFixed(digits) : '—' } -useHead({ title: 'Defense Sim V2' }) +useHead({ title: 'Overwatch' })