diff --git a/src/gausse/components/data/capacitors.json b/src/gausse/components/data/capacitors.json index 7fad7fa..75bdb9a 100644 --- a/src/gausse/components/data/capacitors.json +++ b/src/gausse/components/data/capacitors.json @@ -6,7 +6,8 @@ "esr_ohm": 0.45, "max_current_a": 40.0, "price": 140.0, - "source": "REAL цена: chipdip.ru, категория 'kondensator-400v' (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR ОЦЕНКА 0.3-0.6 Ом. max_current_a — ОЦЕНКА ИМПУЛЬСНОГО тока для одиночного coilgun-выстрела (не ripple из даташита), ограничено ESR/фольгой; в пачке параллельно (как у пользователя, 8шт) суммируется" + "source": "REAL цена: chipdip.ru, категория 'kondensator-400v' (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR ОЦЕНКА 0.3-0.6 Ом. max_current_a — ОЦЕНКА ИМПУЛЬСНОГО тока для одиночного coilgun-выстрела (не ripple из даташита), ограничено ESR/фольгой; в пачке параллельно (как у пользователя, 8шт) суммируется", + "url": "https://www.chipdip.ru/catalog/popular/kondensator-400v" }, { "part_number": "cap-68uf-400v", @@ -15,7 +16,8 @@ "esr_ohm": 0.3, "max_current_a": 60.0, "price": 440.0, - "source": "REAL цена: chipdip.ru (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR ОЦЕНКА. max_current_a — ОЦЕНКА импульсного тока (одиночный выстрел), не ripple" + "source": "REAL цена: chipdip.ru (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR ОЦЕНКА. max_current_a — ОЦЕНКА импульсного тока (одиночный выстрел), не ripple", + "url": "https://www.chipdip.ru/catalog/popular/kondensator-400v" }, { "part_number": "cap-180uf-400v", @@ -24,7 +26,8 @@ "esr_ohm": 0.15, "max_current_a": 120.0, "price": 109.9, - "source": "REAL цена: procontact74.ru, CHANG 180uF 400V 105C (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/180uf-400v-105c-2530-411213/); ESR ОЦЕНКА. max_current_a — ОЦЕНКА импульсного тока, не ripple" + "source": "REAL цена: procontact74.ru, CHANG 180uF 400V 105C (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/180uf-400v-105c-2530-411213/); ESR ОЦЕНКА. max_current_a — ОЦЕНКА импульсного тока, не ripple", + "url": "https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/180uf-400v-105c-2530-411213/" }, { "part_number": "cap-470uf-400v", @@ -33,7 +36,8 @@ "esr_ohm": 0.08, "max_current_a": 250.0, "price": 498.0, - "source": "REAL цена: procontact74.ru, JCCON 470uF 400V 105C 30x45мм (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/kondensator-elektroliticheskiy----470uf-400v-105-c-35-45-cd294-elzet/), проверено, 325.84₽ от 5шт; ESR ОЦЕНКА ~0.05-0.1 Ом. max_current_a — ОЦЕНКА импульсного тока (низкий ESR -> держит сотни А в импульсе), не ripple" + "source": "REAL цена: procontact74.ru, JCCON 470uF 400V 105C 30x45мм (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/kondensator-elektroliticheskiy----470uf-400v-105-c-35-45-cd294-elzet/), проверено, 325.84₽ от 5шт; ESR ОЦЕНКА ~0.05-0.1 Ом. max_current_a — ОЦЕНКА импульсного тока (низкий ESR -> держит сотни А в импульсе), не ripple", + "url": "https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/kondensator-elektroliticheskiy----470uf-400v-105-c-35-45-cd294-elzet/" }, { "part_number": "cap-1000uf-400v", @@ -42,7 +46,8 @@ "esr_ohm": 0.06, "max_current_a": 350.0, "price": 700.0, - "source": "ОЦЕНКА (низкая уверенность по цене): категория подтверждена на procontact74.ru/asenergi.ru, точная цена не подтверждена. max_current_a — ОЦЕНКА импульсного тока для coilgun, не ripple" + "source": "ОЦЕНКА (низкая уверенность по цене): категория подтверждена на procontact74.ru/asenergi.ru, точная цена не подтверждена. max_current_a — ОЦЕНКА импульсного тока для coilgun, не ripple", + "url": "https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/" }, { "part_number": "cap-2200uf-400v", @@ -51,6 +56,7 @@ "esr_ohm": 0.05, "max_current_a": 450.0, "price": 1400.0, - "source": "ОЦЕНКА (низкая уверенность по цене): категория подтверждена на asenergi.ru (https://asenergi.ru/catalog/kondensatory-elektroliticheskie/2200mkf.html). max_current_a — ОЦЕНКА импульсного тока для coilgun, не ripple" + "source": "ОЦЕНКА (низкая уверенность по цене): категория подтверждена на asenergi.ru (https://asenergi.ru/catalog/kondensatory-elektroliticheskie/2200mkf.html). max_current_a — ОЦЕНКА импульсного тока для coilgun, не ripple", + "url": "https://asenergi.ru/catalog/kondensatory-elektroliticheskie/2200mkf.html" } ] diff --git a/src/gausse/components/data/projectile_materials.json b/src/gausse/components/data/projectile_materials.json index 5d06c1b..ec68b36 100644 --- a/src/gausse/components/data/projectile_materials.json +++ b/src/gausse/components/data/projectile_materials.json @@ -5,8 +5,9 @@ "mu_r": 550.0, "b_sat_tesla": 1.9, "price_per_kg": 55.0, - "resistivity_ohm_m": 1.6e-7, - "source": "Цена REAL: горячекатаный круг Ст3, ros-met.com/metallurg-moskva.ru, ~49-60₽/кг (одна из позиций ~51.4₽/кг за тонну); плотность/μr/B_sat/resistivity — ОЦЕНКА (справочные значения для конструкционной стали; удельное сопротивление ~1.6e-7 Ом·м)" + "resistivity_ohm_m": 1.6e-07, + "source": "Цена REAL: горячекатаный круг Ст3, ros-met.com/metallurg-moskva.ru, ~49-60₽/кг (одна из позиций ~51.4₽/кг за тонну); плотность/μr/B_sat/resistivity — ОЦЕНКА (справочные значения для конструкционной стали; удельное сопротивление ~1.6e-7 Ом·м)", + "url": "https://ros-met.com/krug-stalnoy-kupit/" }, { "name": "Сталь 10 (низкоуглеродистая)", @@ -14,8 +15,9 @@ "mu_r": 1500.0, "b_sat_tesla": 2.05, "price_per_kg": 55.0, - "resistivity_ohm_m": 1.4e-7, - "source": "ОЦЕНКА по всем полям: отдельного розничного объявления на 'Сталь 10' не найдено, цена той же полосы, что и Ст3 (~50-70₽/кг); μr выше из-за чистоты; удельное сопротивление ~1.4e-7 Ом·м — справочная оценка" + "resistivity_ohm_m": 1.4e-07, + "source": "ОЦЕНКА по всем полям: отдельного розничного объявления на 'Сталь 10' не найдено, цена той же полосы, что и Ст3 (~50-70₽/кг); μr выше из-за чистоты; удельное сопротивление ~1.4e-7 Ом·м — справочная оценка", + "url": "https://ros-met.com/krug-stalnoy-kupit/" }, { "name": "Армко-железо (чистое железо)", @@ -23,7 +25,8 @@ "mu_r": 3500.0, "b_sat_tesla": 2.15, "price_per_kg": 160.0, - "resistivity_ohm_m": 1.0e-7, - "source": "ОЦЕНКА по всем полям: специализированный товар, розничной цены не найдено; цена ~3x от Ст3; μr/B_sat — справочные для отожжённого чистого железа; удельное сопротивление ~1.0e-7 Ом·м (чище -> ниже)" + "resistivity_ohm_m": 1e-07, + "source": "ОЦЕНКА по всем полям: специализированный товар, розничной цены не найдено; цена ~3x от Ст3; μr/B_sat — справочные для отожжённого чистого железа; удельное сопротивление ~1.0e-7 Ом·м (чище -> ниже)", + "url": "https://ros-met.com/krug-stalnoy-kupit/" } ] diff --git a/src/gausse/components/data/sensors.json b/src/gausse/components/data/sensors.json index 999dcfd..85d6ad2 100644 --- a/src/gausse/components/data/sensors.json +++ b/src/gausse/components/data/sensors.json @@ -4,14 +4,16 @@ "kind": "hall", "propagation_delay_ns": 5000.0, "price": 19.9, - "source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/34-datchiki/datchik-holla-a3144e-34111/), 19.90₽ (6.48₽ от 200шт); время срабатывания на странице не указано, ОЦЕНКА ~5мкс (середина типового диапазона 3-7мкс для А3144-класса)" + "source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/34-datchiki/datchik-holla-a3144e-34111/), 19.90₽ (6.48₽ от 200шт); время срабатывания на странице не указано, ОЦЕНКА ~5мкс (середина типового диапазона 3-7мкс для А3144-класса)", + "url": "https://procontact74.ru/01-elektronnyie-komponentyi-/34-datchiki/datchik-holla-a3144e-34111/" }, { "part_number": "TCST2103", "kind": "optical", "propagation_delay_ns": 9000.0, "price": 220.0, - "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/tcst2103-optopara-shirokogo-naznacheniya-4-pin-vishay-2693015011), 220₽ (161₽ от 200шт); время включения/выключения 8-10мкс — REAL с даташита Vishay, взята середина диапазона" + "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/tcst2103-optopara-shirokogo-naznacheniya-4-pin-vishay-2693015011), 220₽ (161₽ от 200шт); время включения/выключения 8-10мкс — REAL с даташита Vishay, взята середина диапазона", + "url": "https://www.chipdip.ru/product/tcst2103-optopara-shirokogo-naznacheniya-4-pin-vishay-2693015011" }, { "part_number": "inductive-pickup-lm393", @@ -20,6 +22,7 @@ "price": 15.0, "source": "ОЦЕНКА: не готовый компонент, а самодельная схема — виток(-и) провода (цена уже учтена в wires.json) + компаратор LM393 (~15₽, типовая розничная цена); время задержки 1.3мкс — реальный паспортный параметр LM393, но чувствительность/порог ниже — грубая оценка, не датащит-значение", "sensitivity_v_per_mps": 0.01, - "threshold_v": 0.05 + "threshold_v": 0.05, + "url": "https://www.chipdip.ru/search?searchtext=LM393" } ] diff --git a/src/gausse/components/data/switches.json b/src/gausse/components/data/switches.json index 2879ce3..ee2690a 100644 --- a/src/gausse/components/data/switches.json +++ b/src/gausse/components/data/switches.json @@ -8,7 +8,8 @@ "on_voltage_drop_v": 1.5, "turn_on_time_ns": 10000.0, "price": 140.0, - "source": "REAL: КУ202Н, chipdip.ru (https://www.chipdip.ru/product/ku202n) 140₽ / procontact74.ru (https://procontact74.ru/44-tiristory/ku202n-tiristor-10a-400v-44011/) 189₽; Von=1.5В с даташита; время включения ОЦЕНКА ~10мкс (типично для тиристора этого класса, точное значение в листинге не приведено)" + "source": "REAL: КУ202Н, chipdip.ru (https://www.chipdip.ru/product/ku202n) 140₽ / procontact74.ru (https://procontact74.ru/44-tiristory/ku202n-tiristor-10a-400v-44011/) 189₽; Von=1.5В с даташита; время включения ОЦЕНКА ~10мкс (типично для тиристора этого класса, точное значение в листинге не приведено)", + "url": "https://www.chipdip.ru/product/ku202n" }, { "part_number": "BT151-650R", @@ -19,7 +20,8 @@ "on_voltage_drop_v": 1.7, "turn_on_time_ns": 1500.0, "price": 190.0, - "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/bt151-650r), ~180-200₽ (BT151-600R вариант подтверждён на 180₽); Von и время включения ОЦЕНКА (типично для тиристора этого класса, не указаны продавцом)" + "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/bt151-650r), ~180-200₽ (BT151-600R вариант подтверждён на 180₽); Von и время включения ОЦЕНКА (типично для тиристора этого класса, не указаны продавцом)", + "url": "https://www.chipdip.ru/product/bt151-650r" }, { "part_number": "IRFP254PBF", @@ -30,7 +32,8 @@ "on_voltage_drop_v": null, "turn_on_time_ns": 30.0, "price": 39.9, - "source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/43-tranzistory/polevyie--mosfet-/58406-tranzistorirfp254pbfmosfetnch250v23ato247acoriginalbydemontajnogi10mm/); ВНИМАНИЕ: демонтированная (Б/У) деталь, не новая партия; время включения ОЦЕНКА ~30нс (типично для этого класса MOSFET)" + "source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/43-tranzistory/polevyie--mosfet-/58406-tranzistorirfp254pbfmosfetnch250v23ato247acoriginalbydemontajnogi10mm/); ВНИМАНИЕ: демонтированная (Б/У) деталь, не новая партия; время включения ОЦЕНКА ~30нс (типично для этого класса MOSFET)", + "url": "https://procontact74.ru/01-elektronnyie-komponentyi-/43-tranzistory/polevyie--mosfet-/58406-tranzistorirfp254pbfmosfetnch250v23ato247acoriginalbydemontajnogi10mm/" }, { "part_number": "IRFP250PBF", @@ -41,7 +44,8 @@ "on_voltage_drop_v": null, "turn_on_time_ns": 35.0, "price": 320.0, - "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp250), новая деталь, 320₽ (276₽ от 15шт, 245₽ от 150шт); Rds(on)=0.085Ом при 18А/10В с даташита; время включения ОЦЕНКА" + "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp250), новая деталь, 320₽ (276₽ от 15шт, 245₽ от 150шт); Rds(on)=0.085Ом при 18А/10В с даташита; время включения ОЦЕНКА", + "url": "https://www.chipdip.ru/product/irfp250" }, { "part_number": "IRFP4468PBF", @@ -52,7 +56,8 @@ "on_voltage_drop_v": null, "turn_on_time_ns": 40.0, "price": 610.0, - "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp4468pbf), 610₽ (534₽ от 15шт); паспортный максимум 290А при 25°C, взято консервативное практическое значение 180А; Rds(on)=0.0026Ом при 180А/10В с даташита; время включения ОЦЕНКА" + "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp4468pbf), 610₽ (534₽ от 15шт); паспортный максимум 290А при 25°C, взято консервативное практическое значение 180А; Rds(on)=0.0026Ом при 180А/10В с даташита; время включения ОЦЕНКА", + "url": "https://www.chipdip.ru/product/irfp4468pbf" }, { "part_number": "IRG4PC50F", @@ -63,6 +68,7 @@ "on_voltage_drop_v": 1.8, "turn_on_time_ns": 300.0, "price": 504.0, - "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irg4pc50f-8048990896), ~504₽; Vce(sat) и время включения ОЦЕНКА (типично для этого семейства IGBT, не подтверждено со страницы товара)" + "source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irg4pc50f-8048990896), ~504₽; Vce(sat) и время включения ОЦЕНКА (типично для этого семейства IGBT, не подтверждено со страницы товара)", + "url": "https://www.chipdip.ru/product/irg4pc50f-8048990896" } ] diff --git a/src/gausse/components/data/wires.json b/src/gausse/components/data/wires.json index a2a739c..266df9e 100644 --- a/src/gausse/components/data/wires.json +++ b/src/gausse/components/data/wires.json @@ -7,7 +7,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 0.35, "price_per_m": 3.5, - "source": "REAL: chipdip.ru, ПЭТВ-2 0.3мм, 1050₽/200г-катушка ~300м (https://www.chipdip.ru/product/petv-2-d-0.3-mm-provod-emalirovannyy-obmotochnyy-300m-dlina-9000272019)" + "source": "REAL: chipdip.ru, ПЭТВ-2 0.3мм, 1050₽/200г-катушка ~300м (https://www.chipdip.ru/product/petv-2-d-0.3-mm-provod-emalirovannyy-obmotochnyy-300m-dlina-9000272019)", + "url": "https://www.chipdip.ru/product/petv-2-d-0.3-mm-provod-emalirovannyy-obmotochnyy-300m-dlina-9000272019" }, { "part_id": "cu-petv2-0.71mm", @@ -17,7 +18,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 1.98, "price_per_m": 16.2, - "source": "REAL: chipdip.ru, ПЭТВ-2 0.71мм, 890₽/200г-катушка ~55м (https://www.chipdip.ru/product/petv-2-d-0.71-mm)" + "source": "REAL: chipdip.ru, ПЭТВ-2 0.71мм, 890₽/200г-катушка ~55м (https://www.chipdip.ru/product/petv-2-d-0.71-mm)", + "url": "https://www.chipdip.ru/product/petv-2-d-0.71-mm" }, { "part_id": "cu-petv2-1.0mm", @@ -27,7 +29,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 3.93, "price_per_m": 8.445, - "source": "REAL: chipdip.ru, ПЭТВ-2 1.0мм, 1200₽/кг (https://www.chipdip.ru/product0/9000289279); ₽/м пересчитано нами из ₽/кг" + "source": "REAL: chipdip.ru, ПЭТВ-2 1.0мм, 1200₽/кг (https://www.chipdip.ru/product0/9000289279); ₽/м пересчитано нами из ₽/кг", + "url": "https://www.chipdip.ru/product0/9000289279" }, { "part_id": "cu-petv2-1.4mm", @@ -37,7 +40,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 7.7, "price_per_m": 45.266, - "source": "REAL: chipdip.ru, ПЭТВ-2 1.4мм, 3610₽/1.1кг-упаковка (https://www.chipdip.ru/product0/8004178560); ₽/м пересчитано нами из ₽/кг" + "source": "REAL: chipdip.ru, ПЭТВ-2 1.4мм, 3610₽/1.1кг-упаковка (https://www.chipdip.ru/product0/8004178560); ₽/м пересчитано нами из ₽/кг", + "url": "https://www.chipdip.ru/product0/8004178560" }, { "part_id": "cu-petv2-0.8mm", @@ -47,7 +51,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 2.51, "price_per_m": 11.259, - "source": "ОЦЕНКА: товар реален на chipdip.ru (https://www.chipdip.ru/product0/8004178423), но точная цена не подтверждена при парсинге; 2500₽/кг интерполировано между подтверждёнными 0.71мм (~4566₽/кг) и 1.0мм (1200₽/кг)" + "source": "ОЦЕНКА: товар реален на chipdip.ru (https://www.chipdip.ru/product0/8004178423), но точная цена не подтверждена при парсинге; 2500₽/кг интерполировано между подтверждёнными 0.71мм (~4566₽/кг) и 1.0мм (1200₽/кг)", + "url": "https://www.chipdip.ru/product0/8004178423" }, { "part_id": "cu-petv2-2.0mm", @@ -57,7 +62,8 @@ "resistivity_ohm_m": 1.68e-08, "max_current_a": 15.71, "price_per_m": 30.964, - "source": "ОЦЕНКА: chipdip.ru (https://www.chipdip.ru/product0/9000289280), цена частично 'по запросу', взята середина наблюдаемого диапазона 1000-1200₽/кг" + "source": "ОЦЕНКА: chipdip.ru (https://www.chipdip.ru/product0/9000289280), цена частично 'по запросу', взята середина наблюдаемого диапазона 1000-1200₽/кг", + "url": "https://www.chipdip.ru/product0/9000289280" }, { "part_id": "al-0.3mm", @@ -67,7 +73,8 @@ "resistivity_ohm_m": 2.82e-08, "max_current_a": 0.28, "price_per_m": 1.4, - "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)" + "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)", + "url": "https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php" }, { "part_id": "al-0.71mm", @@ -77,7 +84,8 @@ "resistivity_ohm_m": 2.82e-08, "max_current_a": 1.58, "price_per_m": 6.48, - "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)" + "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)", + "url": "https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php" }, { "part_id": "al-1.0mm", @@ -87,7 +95,8 @@ "resistivity_ohm_m": 2.82e-08, "max_current_a": 3.14, "price_per_m": 3.378, - "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)" + "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)", + "url": "https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php" }, { "part_id": "al-1.4mm", @@ -97,6 +106,7 @@ "resistivity_ohm_m": 2.82e-08, "max_current_a": 6.16, "price_per_m": 18.106, - "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)" + "source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)", + "url": "https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php" } -] \ No newline at end of file +] diff --git a/src/gausse/components/schema.py b/src/gausse/components/schema.py index 59746cc..d982ecc 100644 --- a/src/gausse/components/schema.py +++ b/src/gausse/components/schema.py @@ -14,6 +14,7 @@ class WireSpec: max_current_a: float price_per_m: float source: str + url: str | None = None # прямая ссылка на магазин, где купить @dataclass(frozen=True) @@ -25,6 +26,7 @@ class CapacitorSpec: max_current_a: float price: float source: str + url: str | None = None @dataclass(frozen=True) @@ -46,6 +48,7 @@ class CapacitorBank: esr_ohm: float max_current_a: float price: float + url: str | None = None @property def count(self) -> int: @@ -64,6 +67,7 @@ class CapacitorBank: esr_ohm=spec.esr_ohm * n_series / n_parallel, max_current_a=spec.max_current_a * n_parallel, price=spec.price * n_series * n_parallel, + url=spec.url, ) @@ -78,6 +82,7 @@ class SwitchSpec: turn_on_time_ns: float price: float source: str + url: str | None = None @dataclass(frozen=True) @@ -89,6 +94,7 @@ class SensorSpec: source: str sensitivity_v_per_mps: float | None = None threshold_v: float | None = None + url: str | None = None @dataclass(frozen=True) @@ -102,3 +108,4 @@ class ProjectileMaterialSpec: # электрическое удельное сопротивление — для расчёта вихревых потерь в снаряде # (сплошной проводник в импульсном поле). Дефолт ~ конструкционная сталь. resistivity_ohm_m: float = 1.6e-7 + url: str | None = None diff --git a/src/gausse/optim/objective.py b/src/gausse/optim/objective.py index 9bd7835..81a66fb 100644 --- a/src/gausse/optim/objective.py +++ b/src/gausse/optim/objective.py @@ -131,27 +131,37 @@ def build_detail(config, coilgun_result: CoilgunResult, db: ComponentDatabase, i "wire": stage.wire.part_id, "wire_material": stage.wire.material, "wire_gauge_mm": stage.wire.gauge_mm, + "wire_insulation_od_mm": stage.wire.insulation_od_mm, + "wire_url": stage.wire.url, "switch": stage.switch.part_number, "switch_kind": stage.switch.kind, "switch_max_current_a": stage.switch.max_current_a, + "switch_max_voltage_v": stage.switch.max_voltage_v, + "switch_url": stage.switch.url, "sensor": stage.sensor.part_number, "sensor_kind": stage.sensor.kind, + "sensor_url": stage.sensor.url, }, "capacitor_bank": { "base_part": cap_base, "n_series": n_series, "n_parallel": n_parallel, "count": n_series * n_parallel, + "single_capacitance_uf": getattr(cap, "capacitance_uf", 0) * n_series / max(n_parallel, 1), + "single_voltage_rating_v": getattr(cap, "voltage_v", 0) / max(n_series, 1), "total_capacitance_uf": cap.capacitance_uf, "total_voltage_rating_v": cap.voltage_v, "total_esr_ohm": cap.esr_ohm, "max_current_a": cap.max_current_a, + "url": getattr(cap, "url", None), }, "winding": { "turns_per_layer": stage.turns_per_layer, "layers": stage.layers, "total_turns": geometry.total_turns, "coil_length_m": geometry.coil_length_m, + "coil_inner_diameter_m": stage.tube_od_m, # = внешний диаметр трубы + "coil_outer_diameter_m": stage.tube_od_m + 2 * geometry.radial_depth_m, "mean_radius_m": geometry.mean_radius_m, "radial_depth_m": geometry.radial_depth_m, "total_wire_length_m": geometry.total_wire_length_m, @@ -214,7 +224,9 @@ def build_detail(config, coilgun_result: CoilgunResult, db: ComponentDatabase, i "mass_g": projectile.mass_kg * 1000, "mu_r": projectile.material.mu_r, "b_sat_tesla": projectile.material.b_sat_tesla, + "resistivity_ohm_m": projectile.material.resistivity_ohm_m, "fits_in_bore": (tube_inner_d_m is None) or (projectile.diameter_m < tube_inner_d_m), + "url": projectile.material.url, }, "launch": {"initial_x_m": initial_x_m, "initial_v_mps": initial_v_mps}, "n_stages": len(config.stages), diff --git a/src/gausse/report/animate.py b/src/gausse/report/animate.py index 85d2d18..014fac0 100644 --- a/src/gausse/report/animate.py +++ b/src/gausse/report/animate.py @@ -21,44 +21,57 @@ from gausse.sim.coilgun import CoilgunConfig, CoilgunResult def _build_global_timeline(result: CoilgunResult, config: CoilgunConfig, fps: int): - """Возвращает (times, positions, per_stage_current_at_time) с равномерным шагом.""" - segments_t = [] - segments_x = [] - segments_i = [] # ток КАЖДОЙ катушки в момент времени (список массивов той же длины, что t) + """Непрерывная траектория снаряда: коаст (по инерции) + разряды по ступеням. + + Строится ПОСЛЕДОВАТЕЛЬНО (без сортировки по времени, которая рвала + траекторию): между разрядами снаряд летит по инерции от конца прошлого + разряда до начала следующего; во время разряда берём точно посчитанные + discharge_x/v/i. Глобальная координата = центр катушки ступени + локальный + discharge_x. Ток каждой катушки задан только в окне её собственного разряда. + """ n_stages = len(config.stages) + seg_t, seg_x = [], [] + seg_i = [[] for _ in range(n_stages)] + + t_cursor = 0.0 + prev_global_x = None + prev_v = None for outcome in result.stage_outcomes: r = outcome.result - # Баллистический подлёт к датчику: постоянная скорость, восстанавливается аналитически - # (в модели v1 нет трения на этом участке — см. sim/stage.py::_ballistic_derivatives). - t_sensor = r.t_sensor_s if r.t_sensor_s is not None else 0.0 - flight_t = np.linspace(0.0, t_sensor, max(int(t_sensor * fps) + 2, 2)) - flight_x = outcome.entry_x_m + outcome.entry_v_mps * flight_t - flight_global_t = outcome.time_offset_s + flight_t - flight_global_x = outcome.global_coil_center_m + flight_x - flight_currents = [np.zeros_like(flight_t) for _ in range(n_stages)] - flight_currents[outcome.stage_index] = np.zeros_like(flight_t) - segments_t.append(flight_global_t) - segments_x.append(flight_global_x) - segments_i.append(flight_currents) + if r.discharge_t is None or r.discharge_x is None: + continue + disch_global_x = outcome.global_coil_center_m + r.discharge_x + start_global_x = float(disch_global_x[0]) - if r.discharge_t is not None: - discharge_global_t = outcome.time_offset_s + (r.t_fire_s or 0.0) + r.discharge_t - discharge_global_x = outcome.global_coil_center_m + r.discharge_x - discharge_currents = [np.zeros_like(r.discharge_t) for _ in range(n_stages)] - discharge_currents[outcome.stage_index] = r.discharge_i - segments_t.append(discharge_global_t) - segments_x.append(discharge_global_x) - segments_i.append(discharge_currents) + # коаст по инерции от конца прошлого разряда до начала этого + if prev_global_x is not None and prev_v and prev_v > 1e-6: + coast_dist = start_global_x - prev_global_x + coast_dur = max(coast_dist / prev_v, 0.0) + n_coast = max(int(coast_dur * fps) + 2, 2) + ct = np.linspace(0.0, coast_dur, n_coast) + seg_t.append(t_cursor + ct) + seg_x.append(np.linspace(prev_global_x, start_global_x, n_coast)) + for s in range(n_stages): + seg_i[s].append(np.zeros(n_coast)) + t_cursor += coast_dur - times = np.concatenate(segments_t) - positions = np.concatenate(segments_x) - currents = [np.concatenate([seg[stage] for seg in segments_i]) for stage in range(n_stages)] + # окно разряда: точная траектория + ток именно этой катушки + seg_t.append(t_cursor + r.discharge_t) + seg_x.append(disch_global_x) + for s in range(n_stages): + seg_i[s].append(r.discharge_i if s == outcome.stage_index else np.zeros_like(r.discharge_t)) + t_cursor += float(r.discharge_t[-1]) - order = np.argsort(times) - times = times[order] - positions = positions[order] - currents = [c[order] for c in currents] + prev_global_x = float(disch_global_x[-1]) + prev_v = float(r.discharge_v[-1]) if r.discharge_v is not None else outcome.entry_v_mps + + if not seg_t: + raise ValueError("нет данных разряда для анимации") + + times = np.concatenate(seg_t) + positions = np.concatenate(seg_x) + currents = [np.concatenate(seg_i[s]) for s in range(n_stages)] return times, positions, currents @@ -81,20 +94,30 @@ def animate_run(result: CoilgunResult, config: CoilgunConfig, out_path: str, fps ax.set_yticks([]) ax.set_title("Пролёт снаряда через ступени") - tube_line = ax.axhline(0, color="gray", linewidth=2, zorder=1) - coil_dots = [ - ax.scatter([c * 1e3], [0], s=400, c="lightgray", edgecolors="black", zorder=2) - for c in coil_centers - ] - slug_dot = ax.scatter([], [], s=150, c="red", zorder=3) - time_text = ax.text(0.02, 0.9, "", transform=ax.transAxes) + ax.axhline(0, color="#888", linewidth=3, zorder=1) # труба + coil_dots = [] + for k, c in enumerate(coil_centers): + dot = ax.scatter([c * 1e3], [0], s=600, c="lightgray", edgecolors="#333", linewidths=1.5, zorder=2) + ax.annotate(f"катушка {k}", (c * 1e3, 0), textcoords="offset points", xytext=(0, 22), + ha="center", fontsize=8, color="#555") + coil_dots.append(dot) + slug_dot = ax.scatter([], [], s=180, c="#1f4e8c", edgecolors="white", linewidths=1, zorder=3) + time_text = ax.text(0.02, 0.88, "", transform=ax.transAxes, fontsize=10) + + def _coil_color(intensity): + # выкл -> светло-серый; максимум тока -> яркое золото (свечение поля) + t = min(max(intensity, 0.0), 1.0) + off = np.array([0.83, 0.83, 0.83]) + on = np.array([1.0, 0.78, 0.0]) + return tuple(off + (on - off) * t) def update(frame_i): idx = frame_idx[frame_i] slug_dot.set_offsets([[positions[idx] * 1e3, 0]]) for stage_idx, dots in enumerate(coil_dots): intensity = abs(currents[stage_idx][idx]) / max_current_per_stage[stage_idx] - dots.set_color(plt.cm.autumn(1.0 - min(intensity, 1.0))) + dots.set_color(_coil_color(intensity)) + dots.set_sizes([600 + 400 * min(intensity, 1.0)]) # чуть раздувается при разряде time_text.set_text(f"t = {times[idx] * 1e3:.3f} мс") return [slug_dot, time_text, *coil_dots] diff --git a/src/gausse/report/bom.py b/src/gausse/report/bom.py index ffeec4b..2b1bdc1 100644 --- a/src/gausse/report/bom.py +++ b/src/gausse/report/bom.py @@ -15,6 +15,7 @@ class BomLine: unit_price_rub: float total_price_rub: float note: str = "" + url: str | None = None # ссылка на магазин, где купить def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: @@ -30,7 +31,8 @@ def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: quantity=f"{wire_length_m:.2f} м", unit_price_rub=stage.wire.price_per_m, total_price_rub=wire_length_m * stage.wire.price_per_m, - note=f"{geometry.total_turns} витков ({stage.turns_per_layer}x{stage.layers})", + note=f"{geometry.total_turns} витков ({stage.turns_per_layer}x{stage.layers}), ⌀{stage.wire.gauge_mm}мм", + url=stage.wire.url, ) ) cap = stage.capacitor @@ -47,6 +49,7 @@ def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: unit_price_rub=unit_price, total_price_rub=cap.price, note=f"батарея {cap.capacitance_uf:.0f}мкФ {cap.voltage_v:.0f}В, заряд {stage.charge_voltage_v:.0f}В, макс.ток {cap.max_current_a:.0f}А", + url=getattr(cap, "url", None), ) ) lines.append( @@ -56,7 +59,8 @@ def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: quantity="1 шт", unit_price_rub=stage.switch.price, total_price_rub=stage.switch.price, - note=stage.switch.kind, + note=f"{stage.switch.kind}, {stage.switch.max_current_a:.0f}А / {stage.switch.max_voltage_v:.0f}В", + url=stage.switch.url, ) ) lines.append( @@ -67,6 +71,7 @@ def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: unit_price_rub=stage.sensor.price, total_price_rub=stage.sensor.price, note=stage.sensor.kind, + url=stage.sensor.url, ) ) @@ -79,6 +84,7 @@ def build_bom(config: CoilgunConfig, db: ComponentDatabase) -> list[BomLine]: unit_price_rub=config.projectile.material.price_per_kg, total_price_rub=mass_kg * config.projectile.material.price_per_kg, note=f"⌀{config.projectile.diameter_m * 1000:.1f}мм x {config.projectile.length_m * 1000:.1f}мм", + url=config.projectile.material.url, ) ) return lines @@ -89,12 +95,12 @@ def total_cost_rub(lines: list[BomLine]) -> float: def render_bom_text(lines: list[BomLine]) -> str: - rows = ["Ступень\tДеталь\tКол-во\tЦена/ед\tИтого\tПримечание"] + rows = ["Ступень\tДеталь\tКол-во\tЦена/ед\tИтого\tПримечание\tКупить"] for line in lines: stage_label = "-" if line.stage_index is None else str(line.stage_index) rows.append( f"{stage_label}\t{line.part}\t{line.quantity}\t{line.unit_price_rub:.2f}₽\t" - f"{line.total_price_rub:.2f}₽\t{line.note}" + f"{line.total_price_rub:.2f}₽\t{line.note}\t{line.url or ''}" ) - rows.append(f"\t\t\t\tИТОГО: {total_cost_rub(lines):.2f}₽\t") + rows.append(f"\t\t\t\tИТОГО: {total_cost_rub(lines):.2f}₽\t\t") return "\n".join(rows)