Talk:Induction Furnace: Difference between revisions
No edit summary |
|||
| Line 199: | Line 199: | ||
Serial.println(); | Serial.println(); | ||
} | } | ||
= Induction Furnace Development Update = | |||
We have made significant progress on the parametric Induction Furnace model in FreeCAD. This update covers the high-LOD enhancements, a focused core generator, a real-world Bill of Materials, and step-by-step build instructions. | |||
== Model Overview == | |||
We have developed two generator scripts to cater to different needs: | |||
=== Full System Model === | |||
* '''Script:''' `generators/machines.py` | |||
* '''Command:''' `python3 cli.py furnace` | |||
* '''Description:''' A complete industrial setup including the structural frame, concrete platform, safety railings, hydraulic tilting mechanism, and full control panel. | |||
* '''High-LOD Features:''' | |||
* **Hydraulics:** Hydraulic Power Unit (HPU) with reservoir, motor, valve block, and hoses connecting to the tilt cylinder. | |||
* **Electronics:** Detailed ZVS Driver module with PCB, heatsinks, capacitor bank, and choke inductors mounted on an open-frame rack. | |||
* **Cooling:** Explicit water cooling loop with pump, radiator, fan, tank, and hoses. | |||
* **Hardware:** Hex bolt heads at frame joints and pivot points. | |||
* **Casting:** Double-crucible system (Inner Melting Pot + Outer Chamber) with a pouring spout and steel ramp. | |||
=== Focused Core Model === | |||
* '''Script:''' `generators/induction_furnace_core.py` | |||
* '''Command:''' `python3 cli.py furnace-core` | |||
* '''Description:''' A simplified model focusing strictly on the functional components required for melting. | |||
* '''Components:''' | |||
* Induction Circuit (ZVS, Bus Bars) | |||
* Heat Dissipation System (Radiator, Pump, Tank) | |||
* Coil (Copper Tubing) | |||
* Melt Chamber (Outer Crucible) | |||
* Feeder (Hopper) | |||
* Crucible (Inner Pot) | |||
== Bill of Materials (BOM) == | |||
We have sourced real-world parts for the core components. Prices are estimates. | |||
{| class="wikitable" | |||
! Component !! Model Specs !! Real-World Part !! Approx Price | |||
|- | |||
| '''Crucible''' || 300mm Dia x 400mm H || Graphite Crucible #50-#100 (Industrial) || $150 - $300 | |||
|- | |||
| '''Induction Coil''' || 170mm Radius, 16mm Tube || 5/8" Soft Copper Tubing (50ft Coil) || $80 - $120 | |||
|- | |||
| '''Radiator''' || 150x150mm || 120mm Computer Water Cooling Radiator || $20 - $40 | |||
|- | |||
| '''Pump''' || 12V Centrifugal || 12V Water Cooling Pump (PC/Industrial) || $20 - $50 | |||
|- | |||
| '''Hydraulics''' || 150mm Stroke || Hydraulic Cylinder 150mm Stroke || $50 - $100 | |||
|- | |||
| '''Bus Bars''' || 20x100mm Copper || Copper Bus Bar 1/8" x 1" || $30 - $60 | |||
|} | |||
== Build Instructions == | |||
A detailed assembly guide has been generated. | |||
=== Phase 1: Structural & Core === | |||
* Assemble the concrete platform and safety railings. | |||
* Erect the main steel frame and install insulation blocks. | |||
* Insert the Outer Crucible (Chamber) and Inner Crucible (Pot). | |||
=== Phase 2: Induction & Cooling === | |||
* Wind the 5/8" copper tubing to form the coil and mount it over the chamber. | |||
* Install the Radiator, Fan, Pump, and Tank. | |||
* Plumb the cooling loop: Pump -> Radiator -> Coil -> Tank -> Pump. | |||
=== Phase 3: Electronics & Power === | |||
* Mount the Control Panel and Electronics Rack. | |||
* Install the ZVS Driver, Capacitor Bank, and Inductors. | |||
* Connect the ZVS output to the Coil using Copper Bus Plates. | |||
* Connect the Hydraulic Power Unit (HPU) to the tilt cylinder. | |||
== Firmware == | |||
The following Arduino firmware controls the safety loop and cooling system. | |||
<source lang="cpp"> | |||
/* | |||
* Induction Furnace Controller | |||
* Platform: Arduino Uno / Nano | |||
* Description: Monitors safety sensors and controls cooling/power relays. | |||
*/ | |||
// --- Pin Definitions --- | |||
const int PIN_VOLT_SENSOR = A0; // Voltage Divider Input | |||
const int PIN_CURR_SENSOR = A1; // ACS712 or Hall Sensor | |||
const int PIN_TEMP_SENSOR = A2; // NTC Thermistor (Coolant) | |||
const int PIN_SAFETY_SW = 2; // Emergency Stop (NC) | |||
const int PIN_RELAY_POWER = 8; // Main Contactor | |||
const int PIN_RELAY_PUMP = 9; // Cooling Pump | |||
const int PIN_FAN_PWM = 10; // Radiator Fan (PWM) | |||
// --- Constants --- | |||
const float TEMP_CRITICAL = 60.0; // Celsius | |||
const float TEMP_IDLE = 30.0; // Celsius | |||
const int FAN_MIN_SPEED = 50; // 0-255 | |||
const int FAN_MAX_SPEED = 255; | |||
// --- Globals --- | |||
bool safety_ok = false; | |||
float coolant_temp = 0.0; | |||
void setup() { | |||
Serial.begin(9600); | |||
pinMode(PIN_SAFETY_SW, INPUT_PULLUP); | |||
pinMode(PIN_RELAY_POWER, OUTPUT); | |||
pinMode(PIN_RELAY_PUMP, OUTPUT); | |||
pinMode(PIN_FAN_PWM, OUTPUT); | |||
// Safe State | |||
digitalWrite(PIN_RELAY_POWER, LOW); | |||
digitalWrite(PIN_RELAY_PUMP, LOW); | |||
analogWrite(PIN_FAN_PWM, 0); | |||
Serial.println("Furnace Controller Initialized"); | |||
} | |||
void loop() { | |||
// 1. Read Sensors | |||
readSensors(); | |||
// 2. Safety Logic | |||
checkSafety(); | |||
// 3. Control Outputs | |||
controlCooling(); | |||
controlPower(); | |||
// 4. Telemetry | |||
sendTelemetry(); | |||
delay(100); | |||
} | |||
void readSensors() { | |||
// Simplified Temp Calculation (Steinhart-Hart would be better) | |||
int raw_temp = analogRead(PIN_TEMP_SENSOR); | |||
// Map 0-1023 to approx 0-100C for demo | |||
coolant_temp = map(raw_temp, 0, 1023, 0, 100); | |||
// Safety Switch (Active LOW if NC switch is closed) | |||
// If switch opens (pressed), pin goes HIGH (internal pullup? No, usually NC to GND) | |||
// Let's assume NC switch to GND. Closed = LOW = OK. Open = HIGH = STOP. | |||
safety_ok = (digitalRead(PIN_SAFETY_SW) == LOW); | |||
} | |||
void checkSafety() { | |||
if (coolant_temp > TEMP_CRITICAL) { | |||
safety_ok = false; | |||
Serial.println("ERROR: Overheat!"); | |||
} | |||
} | |||
void controlCooling() { | |||
// Pump Logic: Always ON if Power is ON, or if Temp > IDLE (Cool down mode) | |||
bool power_is_active = (digitalRead(PIN_RELAY_POWER) == HIGH); | |||
if (power_is_active || coolant_temp > TEMP_IDLE) { | |||
digitalWrite(PIN_RELAY_PUMP, HIGH); | |||
// Fan Logic: Proportional Control | |||
int fan_speed = map(coolant_temp, TEMP_IDLE, TEMP_CRITICAL, FAN_MIN_SPEED, FAN_MAX_SPEED); | |||
fan_speed = constrain(fan_speed, 0, 255); | |||
analogWrite(PIN_FAN_PWM, fan_speed); | |||
} else { | |||
digitalWrite(PIN_RELAY_PUMP, LOW); | |||
analogWrite(PIN_FAN_PWM, 0); | |||
} | |||
} | |||
void controlPower() { | |||
if (safety_ok) { | |||
// In a real system, we might wait for a "Start" command via Serial | |||
// For this safety controller, we just enable the contactor *allowance*. | |||
// The actual ZVS might be triggered separately. | |||
// Here we assume this relay cuts main DC power. | |||
digitalWrite(PIN_RELAY_POWER, HIGH); | |||
} else { | |||
digitalWrite(PIN_RELAY_POWER, LOW); | |||
} | |||
} | |||
void sendTelemetry() { | |||
Serial.print("TEMP:"); Serial.print(coolant_temp); | |||
Serial.print(",SAFETY:"); Serial.print(safety_ok); | |||
Serial.println(); | |||
} | |||
</source> | |||
== Source Code == | |||
=== Core Generator === | |||
<source lang="python"> | |||
def generate_core_furnace(bridge): | |||
"""Generates the Core Induction Furnace (Circuit, Cooling, Coil, Chamber, Feeder, Crucible).""" | |||
print("Generating Induction Furnace Core...") | |||
code = """ | |||
import Part | |||
import FreeCAD as App | |||
from FreeCAD import Vector | |||
import os | |||
# Create new document | |||
doc_name = "InductionFurnaceCore" | |||
try: | |||
App.closeDocument(doc_name) | |||
except: | |||
pass | |||
doc = App.newDocument(doc_name) | |||
# Parameters | |||
crucible_radius = 150.0 | |||
crucible_height = 400.0 | |||
wall_thickness = 20.0 | |||
coil_radius = 170.0 | |||
coil_pitch = 25.0 | |||
coil_height = 300.0 | |||
tube_radius = 8.0 | |||
# --- 1. Melt Chamber (Outer Crucible) --- | |||
outer = doc.addObject("Part::Cylinder", "Melt_Chamber_Outer") | |||
outer.Radius = crucible_radius | |||
outer.Height = crucible_height | |||
outer.ViewObject.Visibility = False | |||
inner = doc.addObject("Part::Cylinder", "Melt_Chamber_Inner") | |||
inner.Radius = crucible_radius - wall_thickness | |||
inner.Height = crucible_height - wall_thickness | |||
inner.Placement = App.Placement(Vector(0, 0, wall_thickness), App.Rotation()) | |||
inner.ViewObject.Visibility = False | |||
chamber = doc.addObject("Part::Cut", "Melt_Chamber") | |||
chamber.Base = outer | |||
chamber.Tool = inner | |||
chamber.ViewObject.ShapeColor = (0.8, 0.8, 0.8) | |||
# Pouring Spout | |||
spout = doc.addObject("Part::Box", "Pouring_Spout") | |||
spout.Length = 40 | |||
spout.Width = 30 | |||
spout.Height = 20 | |||
spout.Placement = App.Placement(Vector(crucible_radius - 10, -15, crucible_height - 20), App.Rotation()) | |||
spout.ViewObject.ShapeColor = (0.8, 0.8, 0.8) | |||
# Fuse spout | |||
chamber_spout = doc.addObject("Part::Fuse", "Melt_Chamber_With_Spout") | |||
chamber_spout.Base = chamber | |||
chamber_spout.Tool = spout | |||
chamber_spout.ViewObject.ShapeColor = (0.8, 0.8, 0.8) | |||
chamber.ViewObject.Visibility = False | |||
spout.ViewObject.Visibility = False | |||
# --- 2. Crucible (Inner Melting Pot) --- | |||
inner_pot_r = crucible_radius - wall_thickness - 10 | |||
inner_pot_h = crucible_height - 20 | |||
inner_pot = doc.addObject("Part::Cylinder", "Crucible_Inner") | |||
inner_pot.Radius = inner_pot_r | |||
inner_pot.Height = inner_pot_h | |||
inner_pot.Placement = App.Placement(Vector(0, 0, 20), App.Rotation()) | |||
inner_pot.ViewObject.ShapeColor = (0.4, 0.4, 0.4) # Graphite | |||
# Pivots (Trunnions) | |||
inner_pivot_r = 15 | |||
inner_pivot_l = doc.addObject("Part::Cylinder", "Crucible_Pivot_L") | |||
inner_pivot_l.Radius = inner_pivot_r | |||
inner_pivot_l.Height = 30 | |||
inner_pivot_l.Placement = App.Placement(Vector(-(inner_pot_r), 0, inner_pot_h - 50), App.Rotation(Vector(0, 1, 0), 90)) | |||
inner_pivot_r_obj = doc.addObject("Part::Cylinder", "Crucible_Pivot_R") | |||
inner_pivot_r_obj.Radius = inner_pivot_r | |||
inner_pivot_r_obj.Height = 30 | |||
inner_pivot_r_obj.Placement = App.Placement(Vector((inner_pot_r - 30), 0, inner_pot_h - 50), App.Rotation(Vector(0, 1, 0), 90)) | |||
# --- 3. Coil --- | |||
helix = Part.makeHelix(coil_pitch, coil_height, coil_radius) | |||
helix.translate(Vector(0, 0, 50)) | |||
p1 = Vector(coil_radius, 0, 50) | |||
profile_circle = Part.Circle(p1, Vector(0, 1, 0), tube_radius) | |||
profile_wire = Part.Wire(profile_circle.toShape()) | |||
sweep = Part.Wire(helix).makePipeShell([profile_wire], True, True) | |||
coil = doc.addObject("Part::Feature", "Induction_Coil") | |||
coil.Shape = sweep | |||
coil.ViewObject.ShapeColor = (0.8, 0.5, 0.2) | |||
# --- 4. Heat Dissipation System --- | |||
# Radiator | |||
radiator = doc.addObject("Part::Box", "Radiator") | |||
radiator.Length = 150 | |||
radiator.Width = 50 | |||
radiator.Height = 150 | |||
radiator.Placement = App.Placement(Vector(crucible_radius + 225, 120, 0), App.Rotation()) | |||
radiator.ViewObject.ShapeColor = (0.1, 0.1, 0.1) | |||
# Fan | |||
fan = doc.addObject("Part::Cylinder", "Cooling_Fan") | |||
fan.Radius = 40 | |||
fan.Height = 10 | |||
fan.Placement = App.Placement(Vector(crucible_radius + 300, 145, 75), App.Rotation(Vector(0, 1, 0), 90)) | |||
fan.ViewObject.ShapeColor = (0.9, 0.9, 0.9) | |||
# Tank | |||
tank = doc.addObject("Part::Box", "Cooling_Tank") | |||
tank.Length = 200 | |||
tank.Width = 200 | |||
tank.Height = 300 | |||
tank.Placement = App.Placement(Vector(crucible_radius + 200, -100, 0), App.Rotation()) | |||
tank.ViewObject.ShapeColor = (0.2, 0.5, 0.9) | |||
# Pump | |||
pump_body = doc.addObject("Part::Cylinder", "Cooling_Pump") | |||
pump_body.Radius = 40 | |||
pump_body.Height = 100 | |||
pump_body.Placement = App.Placement(Vector(crucible_radius + 250, -100, 300), App.Rotation(Vector(1,0,0), 90)) | |||
pump_body.ViewObject.ShapeColor = (0.2, 0.2, 0.2) | |||
# Hoses | |||
hose1_a = doc.addObject("Part::Cylinder", "Hose_Pump_Rad_1") | |||
hose1_a.Radius = 8 | |||
hose1_a.Height = 220 | |||
hose1_a.Placement = App.Placement(Vector(crucible_radius + 210, -100, 300), App.Rotation(Vector(1,0,0), -90)) | |||
hose1_a.ViewObject.ShapeColor = (0.1, 0.1, 0.8) | |||
hose1_b = doc.addObject("Part::Cylinder", "Hose_Pump_Rad_2") | |||
hose1_b.Radius = 8 | |||
hose1_b.Height = 200 | |||
hose1_b.Placement = App.Placement(Vector(crucible_radius + 210, 120, 300), App.Rotation(Vector(0,1,0), 180)) | |||
hose1_b.ViewObject.ShapeColor = (0.1, 0.1, 0.8) | |||
hose2 = doc.addObject("Part::Cylinder", "Hose_Rad_Coil") | |||
hose2.Radius = 8 | |||
hose2.Height = 150 | |||
hose2.Placement = App.Placement(Vector(crucible_radius + 225, 120, 20), App.Rotation(Vector(0,0,1), 45)) | |||
hose2.ViewObject.ShapeColor = (0.1, 0.1, 0.8) | |||
hose3 = doc.addObject("Part::Cylinder", "Hose_Coil_Tank") | |||
hose3.Radius = 8 | |||
hose3.Height = 200 | |||
hose3.Placement = App.Placement(Vector(coil_radius, 0, 350), App.Rotation(Vector(1,0,0), 45)) | |||
hose3.ViewObject.ShapeColor = (0.8, 0.1, 0.1) | |||
hose4 = doc.addObject("Part::Cylinder", "Hose_Tank_Pump") | |||
hose4.Radius = 8 | |||
hose4.Height = 100 | |||
hose4.Placement = App.Placement(Vector(crucible_radius + 200, -100, 20), App.Rotation()) | |||
hose4.ViewObject.ShapeColor = (0.1, 0.1, 0.8) | |||
# --- 5. Induction Furnace Circuit --- | |||
# Rack (Simplified for core view, or just floating components? User asked for Circuit. I'll keep the rack to hold them) | |||
rack_x = -(crucible_radius + 400) | |||
rack_y = -100 | |||
rack_z = 0 | |||
rack_w = 200 | |||
rack_l = 300 | |||
rack_h = 400 | |||
# Legs | |||
for i, (dx, dy) in enumerate([(0,0), (rack_l, 0), (0, rack_w), (rack_l, rack_w)]): | |||
leg = doc.addObject("Part::Box", f"Rack_Leg_{i}") | |||
leg.Length = 20 | |||
leg.Width = 20 | |||
leg.Height = rack_h | |||
leg.Placement = App.Placement(Vector(rack_x + dx - 10, rack_y + dy - 10, rack_z), App.Rotation()) | |||
leg.ViewObject.ShapeColor = (0.3, 0.3, 0.3) | |||
# Shelves | |||
rack_top = doc.addObject("Part::Box", "Rack_Top") | |||
rack_top.Length = rack_l | |||
rack_top.Width = rack_w | |||
rack_top.Height = 10 | |||
rack_top.Placement = App.Placement(Vector(rack_x, rack_y, rack_z + rack_h), App.Rotation()) | |||
rack_top.ViewObject.ShapeColor = (0.4, 0.4, 0.4) | |||
rack_shelf = doc.addObject("Part::Box", "Rack_Shelf") | |||
rack_shelf.Length = rack_l | |||
rack_shelf.Width = rack_w | |||
rack_shelf.Height = 10 | |||
rack_shelf.Placement = App.Placement(Vector(rack_x, rack_y, rack_z + 100), App.Rotation()) | |||
rack_shelf.ViewObject.ShapeColor = (0.4, 0.4, 0.4) | |||
# ZVS Driver | |||
pcb = doc.addObject("Part::Box", "ZVS_PCB") | |||
pcb.Length = 200 | |||
pcb.Width = 150 | |||
pcb.Height = 5 | |||
pcb.Placement = App.Placement(Vector(-(crucible_radius + 400) + 50, -50, 405), App.Rotation()) | |||
pcb.ViewObject.ShapeColor = (0.0, 0.5, 0.0) | |||
hs1 = doc.addObject("Part::Box", "Heatsink_1") | |||
hs1.Length = 80 | |||
hs1.Width = 40 | |||
hs1.Height = 50 | |||
hs1.Placement = App.Placement(Vector(-(crucible_radius + 400) + 60, -40, 410), App.Rotation()) | |||
hs1.ViewObject.ShapeColor = (0.1, 0.1, 0.1) | |||
hs2 = doc.addObject("Part::Box", "Heatsink_2") | |||
hs2.Length = 80 | |||
hs2.Width = 40 | |||
hs2.Height = 50 | |||
hs2.Placement = App.Placement(Vector(-(crucible_radius + 400) + 60, 50, 410), App.Rotation()) | |||
hs2.ViewObject.ShapeColor = (0.1, 0.1, 0.1) | |||
for i in range(3): | |||
for j in range(2): | |||
cap = doc.addObject("Part::Cylinder", f"Capacitor_{i}_{j}") | |||
cap.Radius = 10 | |||
cap.Height = 30 | |||
cap.Placement = App.Placement(Vector(-(crucible_radius + 400) + 160 + (i*25), -20 + (j*25), 410), App.Rotation()) | |||
cap.ViewObject.ShapeColor = (0.8, 0.2, 0.2) | |||
ind1 = doc.addObject("Part::Cylinder", "Choke_Inductor_1") | |||
ind1.Radius = 20 | |||
ind1.Height = 15 | |||
ind1.Placement = App.Placement(Vector(-(crucible_radius + 400) + 200, 60, 410), App.Rotation()) | |||
ind1.ViewObject.ShapeColor = (0.6, 0.4, 0.2) | |||
# Bus Plates | |||
plate1 = doc.addObject("Part::Box", "Bus_Plate_1") | |||
plate1.Length = 200 | |||
plate1.Width = 40 | |||
plate1.Height = 5 | |||
plate1.Placement = App.Placement(Vector(-(crucible_radius + 150), 0, 300), App.Rotation(Vector(0,1,0), -20)) | |||
plate1.ViewObject.ShapeColor = (0.8, 0.4, 0.0) | |||
# Bus Bars | |||
bar1 = doc.addObject("Part::Box", "Bus_Bar_1") | |||
bar1.Length = 200 | |||
bar1.Width = 20 | |||
bar1.Height = 100 | |||
bar1.Placement = App.Placement(Vector(-(crucible_radius + 100), 10, 100), App.Rotation()) | |||
bar1.ViewObject.ShapeColor = (0.8, 0.4, 0.0) | |||
bar2 = doc.addObject("Part::Box", "Bus_Bar_2") | |||
bar2.Length = 200 | |||
bar2.Width = 20 | |||
bar2.Height = 100 | |||
bar2.Placement = App.Placement(Vector(-(crucible_radius + 100), -30, 100), App.Rotation()) | |||
bar2.ViewObject.ShapeColor = (0.8, 0.4, 0.0) | |||
# --- 6. Feeder --- | |||
hopper = doc.addObject("Part::Cone", "Feeder_Hopper") | |||
hopper.Radius1 = 50 | |||
hopper.Radius2 = 150 | |||
hopper.Height = 200 | |||
hopper.Placement = App.Placement(Vector(0, 0, crucible_height + 150), App.Rotation()) | |||
hopper.ViewObject.ShapeColor = (0.6, 0.6, 0.7) | |||
beam = doc.addObject("Part::Box", "Feeder_Support") | |||
beam.Length = 40 | |||
beam.Width = 300 | |||
beam.Height = 40 | |||
beam.Placement = App.Placement(Vector(-(crucible_radius + 50), -150, crucible_height + 250), App.Rotation()) | |||
doc.recompute() | |||
home = os.path.expanduser("~") | |||
output_path = os.path.join(home, "Antigravity_24_Freecad", "outputs", "InductionFurnaceCore.FCStd") | |||
doc.saveAs(output_path) | |||
""" | |||
result = bridge.send_command({ | |||
"action": "execute_code", | |||
"params": { | |||
"code": code, | |||
"description": "Create Induction Furnace Core" | |||
} | |||
}) | |||
print("Result:", result) | |||
return result | |||
</source> | |||
== Resources == | |||
* **Output Models:** `Antigravity_24_Freecad/outputs/InductionFurnace.FCStd` | |||
Revision as of 04:11, 8 December 2025
The boys Induction Furnace
Induction Furnace Development Update
We have made significant progress on the parametric Induction Furnace model in FreeCAD. This update covers the high-LOD enhancements, a focused core generator, a real-world Bill of Materials, and step-by-step build instructions.
Model Overview
We have developed two generator scripts to cater to different needs:
Full System Model
- Script: `generators/machines.py`
- Command: `python3 cli.py furnace`
- Description: A complete industrial setup including the structural frame, concrete platform, safety railings, hydraulic tilting mechanism, and full control panel.
- High-LOD Features:
Hydraulics: Hydraulic Power Unit (HPU) with reservoir, motor, valve block, and hoses connecting to the tilt cylinder.
Electronics: Detailed ZVS Driver module with PCB, heatsinks, capacitor bank, and choke inductors mounted on an open-frame rack.
Cooling: Explicit water cooling loop with pump, radiator, fan, tank, and hoses.
Hardware: Hex bolt heads at frame joints and pivot points.
Casting: Double-crucible system (Inner Melting Pot + Outer Chamber) with a pouring spout and steel ramp.
Focused Core Model
- Script: `generators/induction_furnace_core.py`
- Command: `python3 cli.py furnace-core`
- Description: A simplified model focusing strictly on the functional components required for melting.
- Components:
Induction Circuit (ZVS, Bus Bars)
Heat Dissipation System (Radiator, Pump, Tank)
Coil (Copper Tubing)
Melt Chamber (Outer Crucible)
Feeder (Hopper)
Crucible (Inner Pot)
Bill of Materials (BOM)
We have sourced real-world parts for the core components. Prices are estimates.
| Component | Model Specs | Real-World Part | Approx Price |
|---|---|---|---|
| Crucible | 300mm Dia x 400mm H | Graphite Crucible #50-#100 (Industrial) | $150 - $300 |
| Induction Coil | 170mm Radius, 16mm Tube | 5/8" Soft Copper Tubing (50ft Coil) | $80 - $120 |
| Radiator | 150x150mm | 120mm Computer Water Cooling Radiator | $20 - $40 |
| Pump | 12V Centrifugal | 12V Water Cooling Pump (PC/Industrial) | $20 - $50 |
| Hydraulics | 150mm Stroke | Hydraulic Cylinder 150mm Stroke | $50 - $100 |
| Bus Bars | 20x100mm Copper | Copper Bus Bar 1/8" x 1" | $30 - $60 |
Build Instructions
A detailed assembly guide has been generated.
Phase 1: Structural & Core
- Assemble the concrete platform and safety railings.
- Erect the main steel frame and install insulation blocks.
- Insert the Outer Crucible (Chamber) and Inner Crucible (Pot).
Phase 2: Induction & Cooling
- Wind the 5/8" copper tubing to form the coil and mount it over the chamber.
- Install the Radiator, Fan, Pump, and Tank.
- Plumb the cooling loop: Pump -> Radiator -> Coil -> Tank -> Pump.
Phase 3: Electronics & Power
- Mount the Control Panel and Electronics Rack.
- Install the ZVS Driver, Capacitor Bank, and Inductors.
- Connect the ZVS output to the Coil using Copper Bus Plates.
- Connect the Hydraulic Power Unit (HPU) to the tilt cylinder.
Resources
- **Source Code:** `Antigravity_24_Freecad/generators/`
- **Output Models:** `Antigravity_24_Freecad/outputs/InductionFurnace.FCStd`
Arduino Control
- Induction Furnace Controller
* Platform: Arduino Uno / Nano * Description: Monitors safety sensors and controls cooling/power relays. */
// --- Pin Definitions --- const int PIN_VOLT_SENSOR = A0; // Voltage Divider Input
const int PIN_CURR_SENSOR = A1; // ACS712 or Hall Sensor
const int PIN_TEMP_SENSOR = A2; // NTC Thermistor (Coolant)
const int PIN_SAFETY_SW = 2; // Emergency Stop (NC)
const int PIN_RELAY_POWER = 8; // Main Contactor
const int PIN_RELAY_PUMP = 9; // Cooling Pump
const int PIN_FAN_PWM = 10; // Radiator Fan (PWM)
// --- Constants ---
const float TEMP_CRITICAL = 60.0; // Celsius
const float TEMP_IDLE = 30.0; // Celsius
const int FAN_MIN_SPEED = 50; // 0-255
const int FAN_MAX_SPEED = 255;
// --- Globals --- bool safety_ok = false; float coolant_temp = 0.0;
void setup() {
Serial.begin(9600);
pinMode(PIN_SAFETY_SW, INPUT_PULLUP);
pinMode(PIN_RELAY_POWER, OUTPUT);
pinMode(PIN_RELAY_PUMP, OUTPUT);
pinMode(PIN_FAN_PWM, OUTPUT);
// Safe State
digitalWrite(PIN_RELAY_POWER, LOW);
digitalWrite(PIN_RELAY_PUMP, LOW);
analogWrite(PIN_FAN_PWM, 0);
Serial.println("Furnace Controller Initialized");
}
void loop() {
// 1. Read Sensors readSensors(); // 2. Safety Logic checkSafety(); // 3. Control Outputs controlCooling(); controlPower(); // 4. Telemetry sendTelemetry(); delay(100);
}
void readSensors() {
// Simplified Temp Calculation (Steinhart-Hart would be better)
int raw_temp = analogRead(PIN_TEMP_SENSOR);
// Map 0-1023 to approx 0-100C for demo
coolant_temp = map(raw_temp, 0, 1023, 0, 100); // Safety Switch (Active LOW if NC switch is closed)
// If switch opens (pressed), pin goes HIGH (internal pullup? No, usually NC to GND)
// Let's assume NC switch to GND. Closed = LOW = OK. Open = HIGH = STOP.
safety_ok = (digitalRead(PIN_SAFETY_SW) == LOW);
}
void checkSafety() {
if (coolant_temp > TEMP_CRITICAL) {
safety_ok = false;
Serial.println("ERROR: Overheat!");
}
}
void controlCooling() {
// Pump Logic: Always ON if Power is ON, or if Temp > IDLE (Cool down mode)
bool power_is_active = (digitalRead(PIN_RELAY_POWER) == HIGH);
if (power_is_active || coolant_temp > TEMP_IDLE) {
digitalWrite(PIN_RELAY_PUMP, HIGH);
// Fan Logic: Proportional Control
int fan_speed = map(coolant_temp, TEMP_IDLE, TEMP_CRITICAL, FAN_MIN_SPEED, FAN_MAX_SPEED);
fan_speed = constrain(fan_speed, 0, 255);
analogWrite(PIN_FAN_PWM, fan_speed);
} else {
digitalWrite(PIN_RELAY_PUMP, LOW);
analogWrite(PIN_FAN_PWM, 0);
}
}
void controlPower() {
if (safety_ok) {
// In a real system, we might wait for a "Start" command via Serial
// For this safety controller, we just enable the contactor *allowance*.
// The actual ZVS might be triggered separately.
// Here we assume this relay cuts main DC power.
digitalWrite(PIN_RELAY_POWER, HIGH);
} else {
digitalWrite(PIN_RELAY_POWER, LOW);
}
}
void sendTelemetry() {
Serial.print("TEMP:"); Serial.print(coolant_temp);
Serial.print(",SAFETY:"); Serial.print(safety_ok);
Serial.println();
}
Induction Furnace Development Update
We have made significant progress on the parametric Induction Furnace model in FreeCAD. This update covers the high-LOD enhancements, a focused core generator, a real-world Bill of Materials, and step-by-step build instructions.
Model Overview
We have developed two generator scripts to cater to different needs:
Full System Model
- Script: `generators/machines.py`
- Command: `python3 cli.py furnace`
- Description: A complete industrial setup including the structural frame, concrete platform, safety railings, hydraulic tilting mechanism, and full control panel.
- High-LOD Features:
* **Hydraulics:** Hydraulic Power Unit (HPU) with reservoir, motor, valve block, and hoses connecting to the tilt cylinder. * **Electronics:** Detailed ZVS Driver module with PCB, heatsinks, capacitor bank, and choke inductors mounted on an open-frame rack. * **Cooling:** Explicit water cooling loop with pump, radiator, fan, tank, and hoses. * **Hardware:** Hex bolt heads at frame joints and pivot points. * **Casting:** Double-crucible system (Inner Melting Pot + Outer Chamber) with a pouring spout and steel ramp.
Focused Core Model
- Script: `generators/induction_furnace_core.py`
- Command: `python3 cli.py furnace-core`
- Description: A simplified model focusing strictly on the functional components required for melting.
- Components:
* Induction Circuit (ZVS, Bus Bars) * Heat Dissipation System (Radiator, Pump, Tank) * Coil (Copper Tubing) * Melt Chamber (Outer Crucible) * Feeder (Hopper) * Crucible (Inner Pot)
Bill of Materials (BOM)
We have sourced real-world parts for the core components. Prices are estimates.
| Component | Model Specs | Real-World Part | Approx Price |
|---|---|---|---|
| Crucible | 300mm Dia x 400mm H | Graphite Crucible #50-#100 (Industrial) | $150 - $300 |
| Induction Coil | 170mm Radius, 16mm Tube | 5/8" Soft Copper Tubing (50ft Coil) | $80 - $120 |
| Radiator | 150x150mm | 120mm Computer Water Cooling Radiator | $20 - $40 |
| Pump | 12V Centrifugal | 12V Water Cooling Pump (PC/Industrial) | $20 - $50 |
| Hydraulics | 150mm Stroke | Hydraulic Cylinder 150mm Stroke | $50 - $100 |
| Bus Bars | 20x100mm Copper | Copper Bus Bar 1/8" x 1" | $30 - $60 |
Build Instructions
A detailed assembly guide has been generated.
Phase 1: Structural & Core
- Assemble the concrete platform and safety railings.
- Erect the main steel frame and install insulation blocks.
- Insert the Outer Crucible (Chamber) and Inner Crucible (Pot).
Phase 2: Induction & Cooling
- Wind the 5/8" copper tubing to form the coil and mount it over the chamber.
- Install the Radiator, Fan, Pump, and Tank.
- Plumb the cooling loop: Pump -> Radiator -> Coil -> Tank -> Pump.
Phase 3: Electronics & Power
- Mount the Control Panel and Electronics Rack.
- Install the ZVS Driver, Capacitor Bank, and Inductors.
- Connect the ZVS output to the Coil using Copper Bus Plates.
- Connect the Hydraulic Power Unit (HPU) to the tilt cylinder.
Firmware
The following Arduino firmware controls the safety loop and cooling system. <source lang="cpp"> /*
* Induction Furnace Controller * Platform: Arduino Uno / Nano * Description: Monitors safety sensors and controls cooling/power relays. */
// --- Pin Definitions --- const int PIN_VOLT_SENSOR = A0; // Voltage Divider Input const int PIN_CURR_SENSOR = A1; // ACS712 or Hall Sensor const int PIN_TEMP_SENSOR = A2; // NTC Thermistor (Coolant) const int PIN_SAFETY_SW = 2; // Emergency Stop (NC) const int PIN_RELAY_POWER = 8; // Main Contactor const int PIN_RELAY_PUMP = 9; // Cooling Pump const int PIN_FAN_PWM = 10; // Radiator Fan (PWM) // --- Constants --- const float TEMP_CRITICAL = 60.0; // Celsius const float TEMP_IDLE = 30.0; // Celsius const int FAN_MIN_SPEED = 50; // 0-255 const int FAN_MAX_SPEED = 255; // --- Globals --- bool safety_ok = false; float coolant_temp = 0.0; void setup() {
Serial.begin(9600);
pinMode(PIN_SAFETY_SW, INPUT_PULLUP);
pinMode(PIN_RELAY_POWER, OUTPUT);
pinMode(PIN_RELAY_PUMP, OUTPUT);
pinMode(PIN_FAN_PWM, OUTPUT);
// Safe State
digitalWrite(PIN_RELAY_POWER, LOW);
digitalWrite(PIN_RELAY_PUMP, LOW);
analogWrite(PIN_FAN_PWM, 0);
Serial.println("Furnace Controller Initialized");
} void loop() {
// 1. Read Sensors readSensors(); // 2. Safety Logic checkSafety(); // 3. Control Outputs controlCooling(); controlPower(); // 4. Telemetry sendTelemetry(); delay(100);
} void readSensors() {
// Simplified Temp Calculation (Steinhart-Hart would be better) int raw_temp = analogRead(PIN_TEMP_SENSOR); // Map 0-1023 to approx 0-100C for demo coolant_temp = map(raw_temp, 0, 1023, 0, 100); // Safety Switch (Active LOW if NC switch is closed) // If switch opens (pressed), pin goes HIGH (internal pullup? No, usually NC to GND) // Let's assume NC switch to GND. Closed = LOW = OK. Open = HIGH = STOP. safety_ok = (digitalRead(PIN_SAFETY_SW) == LOW);
} void checkSafety() {
if (coolant_temp > TEMP_CRITICAL) {
safety_ok = false;
Serial.println("ERROR: Overheat!");
}
} void controlCooling() {
// Pump Logic: Always ON if Power is ON, or if Temp > IDLE (Cool down mode)
bool power_is_active = (digitalRead(PIN_RELAY_POWER) == HIGH);
if (power_is_active || coolant_temp > TEMP_IDLE) {
digitalWrite(PIN_RELAY_PUMP, HIGH);
// Fan Logic: Proportional Control
int fan_speed = map(coolant_temp, TEMP_IDLE, TEMP_CRITICAL, FAN_MIN_SPEED, FAN_MAX_SPEED);
fan_speed = constrain(fan_speed, 0, 255);
analogWrite(PIN_FAN_PWM, fan_speed);
} else {
digitalWrite(PIN_RELAY_PUMP, LOW);
analogWrite(PIN_FAN_PWM, 0);
}
} void controlPower() {
if (safety_ok) {
// In a real system, we might wait for a "Start" command via Serial
// For this safety controller, we just enable the contactor *allowance*.
// The actual ZVS might be triggered separately.
// Here we assume this relay cuts main DC power.
digitalWrite(PIN_RELAY_POWER, HIGH);
} else {
digitalWrite(PIN_RELAY_POWER, LOW);
}
} void sendTelemetry() {
Serial.print("TEMP:"); Serial.print(coolant_temp);
Serial.print(",SAFETY:"); Serial.print(safety_ok);
Serial.println();
} </source>
Source Code
Core Generator
<source lang="python"> def generate_core_furnace(bridge):
"""Generates the Core Induction Furnace (Circuit, Cooling, Coil, Chamber, Feeder, Crucible)."""
print("Generating Induction Furnace Core...")
code = """
import Part import FreeCAD as App from FreeCAD import Vector import os
- Create new document
doc_name = "InductionFurnaceCore" try:
App.closeDocument(doc_name)
except:
pass
doc = App.newDocument(doc_name)
- Parameters
crucible_radius = 150.0 crucible_height = 400.0 wall_thickness = 20.0 coil_radius = 170.0 coil_pitch = 25.0 coil_height = 300.0 tube_radius = 8.0
- --- 1. Melt Chamber (Outer Crucible) ---
outer = doc.addObject("Part::Cylinder", "Melt_Chamber_Outer") outer.Radius = crucible_radius outer.Height = crucible_height outer.ViewObject.Visibility = False inner = doc.addObject("Part::Cylinder", "Melt_Chamber_Inner") inner.Radius = crucible_radius - wall_thickness inner.Height = crucible_height - wall_thickness inner.Placement = App.Placement(Vector(0, 0, wall_thickness), App.Rotation()) inner.ViewObject.Visibility = False chamber = doc.addObject("Part::Cut", "Melt_Chamber") chamber.Base = outer chamber.Tool = inner chamber.ViewObject.ShapeColor = (0.8, 0.8, 0.8)
- Pouring Spout
spout = doc.addObject("Part::Box", "Pouring_Spout") spout.Length = 40 spout.Width = 30 spout.Height = 20 spout.Placement = App.Placement(Vector(crucible_radius - 10, -15, crucible_height - 20), App.Rotation()) spout.ViewObject.ShapeColor = (0.8, 0.8, 0.8)
- Fuse spout
chamber_spout = doc.addObject("Part::Fuse", "Melt_Chamber_With_Spout") chamber_spout.Base = chamber chamber_spout.Tool = spout chamber_spout.ViewObject.ShapeColor = (0.8, 0.8, 0.8) chamber.ViewObject.Visibility = False spout.ViewObject.Visibility = False
- --- 2. Crucible (Inner Melting Pot) ---
inner_pot_r = crucible_radius - wall_thickness - 10 inner_pot_h = crucible_height - 20 inner_pot = doc.addObject("Part::Cylinder", "Crucible_Inner") inner_pot.Radius = inner_pot_r inner_pot.Height = inner_pot_h inner_pot.Placement = App.Placement(Vector(0, 0, 20), App.Rotation()) inner_pot.ViewObject.ShapeColor = (0.4, 0.4, 0.4) # Graphite
- Pivots (Trunnions)
inner_pivot_r = 15 inner_pivot_l = doc.addObject("Part::Cylinder", "Crucible_Pivot_L") inner_pivot_l.Radius = inner_pivot_r inner_pivot_l.Height = 30 inner_pivot_l.Placement = App.Placement(Vector(-(inner_pot_r), 0, inner_pot_h - 50), App.Rotation(Vector(0, 1, 0), 90)) inner_pivot_r_obj = doc.addObject("Part::Cylinder", "Crucible_Pivot_R") inner_pivot_r_obj.Radius = inner_pivot_r inner_pivot_r_obj.Height = 30 inner_pivot_r_obj.Placement = App.Placement(Vector((inner_pot_r - 30), 0, inner_pot_h - 50), App.Rotation(Vector(0, 1, 0), 90))
- --- 3. Coil ---
helix = Part.makeHelix(coil_pitch, coil_height, coil_radius) helix.translate(Vector(0, 0, 50)) p1 = Vector(coil_radius, 0, 50) profile_circle = Part.Circle(p1, Vector(0, 1, 0), tube_radius) profile_wire = Part.Wire(profile_circle.toShape()) sweep = Part.Wire(helix).makePipeShell([profile_wire], True, True) coil = doc.addObject("Part::Feature", "Induction_Coil") coil.Shape = sweep coil.ViewObject.ShapeColor = (0.8, 0.5, 0.2)
- --- 4. Heat Dissipation System ---
- Radiator
radiator = doc.addObject("Part::Box", "Radiator") radiator.Length = 150 radiator.Width = 50 radiator.Height = 150 radiator.Placement = App.Placement(Vector(crucible_radius + 225, 120, 0), App.Rotation()) radiator.ViewObject.ShapeColor = (0.1, 0.1, 0.1)
- Fan
fan = doc.addObject("Part::Cylinder", "Cooling_Fan") fan.Radius = 40 fan.Height = 10 fan.Placement = App.Placement(Vector(crucible_radius + 300, 145, 75), App.Rotation(Vector(0, 1, 0), 90)) fan.ViewObject.ShapeColor = (0.9, 0.9, 0.9)
- Tank
tank = doc.addObject("Part::Box", "Cooling_Tank") tank.Length = 200 tank.Width = 200 tank.Height = 300 tank.Placement = App.Placement(Vector(crucible_radius + 200, -100, 0), App.Rotation()) tank.ViewObject.ShapeColor = (0.2, 0.5, 0.9)
- Pump
pump_body = doc.addObject("Part::Cylinder", "Cooling_Pump") pump_body.Radius = 40 pump_body.Height = 100 pump_body.Placement = App.Placement(Vector(crucible_radius + 250, -100, 300), App.Rotation(Vector(1,0,0), 90)) pump_body.ViewObject.ShapeColor = (0.2, 0.2, 0.2)
- Hoses
hose1_a = doc.addObject("Part::Cylinder", "Hose_Pump_Rad_1") hose1_a.Radius = 8 hose1_a.Height = 220 hose1_a.Placement = App.Placement(Vector(crucible_radius + 210, -100, 300), App.Rotation(Vector(1,0,0), -90)) hose1_a.ViewObject.ShapeColor = (0.1, 0.1, 0.8) hose1_b = doc.addObject("Part::Cylinder", "Hose_Pump_Rad_2") hose1_b.Radius = 8 hose1_b.Height = 200 hose1_b.Placement = App.Placement(Vector(crucible_radius + 210, 120, 300), App.Rotation(Vector(0,1,0), 180)) hose1_b.ViewObject.ShapeColor = (0.1, 0.1, 0.8) hose2 = doc.addObject("Part::Cylinder", "Hose_Rad_Coil") hose2.Radius = 8 hose2.Height = 150 hose2.Placement = App.Placement(Vector(crucible_radius + 225, 120, 20), App.Rotation(Vector(0,0,1), 45)) hose2.ViewObject.ShapeColor = (0.1, 0.1, 0.8) hose3 = doc.addObject("Part::Cylinder", "Hose_Coil_Tank") hose3.Radius = 8 hose3.Height = 200 hose3.Placement = App.Placement(Vector(coil_radius, 0, 350), App.Rotation(Vector(1,0,0), 45)) hose3.ViewObject.ShapeColor = (0.8, 0.1, 0.1) hose4 = doc.addObject("Part::Cylinder", "Hose_Tank_Pump") hose4.Radius = 8 hose4.Height = 100 hose4.Placement = App.Placement(Vector(crucible_radius + 200, -100, 20), App.Rotation()) hose4.ViewObject.ShapeColor = (0.1, 0.1, 0.8)
- --- 5. Induction Furnace Circuit ---
- Rack (Simplified for core view, or just floating components? User asked for Circuit. I'll keep the rack to hold them)
rack_x = -(crucible_radius + 400) rack_y = -100 rack_z = 0 rack_w = 200 rack_l = 300 rack_h = 400
- Legs
for i, (dx, dy) in enumerate([(0,0), (rack_l, 0), (0, rack_w), (rack_l, rack_w)]):
leg = doc.addObject("Part::Box", f"Rack_Leg_{i}")
leg.Length = 20
leg.Width = 20
leg.Height = rack_h
leg.Placement = App.Placement(Vector(rack_x + dx - 10, rack_y + dy - 10, rack_z), App.Rotation())
leg.ViewObject.ShapeColor = (0.3, 0.3, 0.3)
- Shelves
rack_top = doc.addObject("Part::Box", "Rack_Top") rack_top.Length = rack_l rack_top.Width = rack_w rack_top.Height = 10 rack_top.Placement = App.Placement(Vector(rack_x, rack_y, rack_z + rack_h), App.Rotation()) rack_top.ViewObject.ShapeColor = (0.4, 0.4, 0.4) rack_shelf = doc.addObject("Part::Box", "Rack_Shelf") rack_shelf.Length = rack_l rack_shelf.Width = rack_w rack_shelf.Height = 10 rack_shelf.Placement = App.Placement(Vector(rack_x, rack_y, rack_z + 100), App.Rotation()) rack_shelf.ViewObject.ShapeColor = (0.4, 0.4, 0.4)
- ZVS Driver
pcb = doc.addObject("Part::Box", "ZVS_PCB") pcb.Length = 200 pcb.Width = 150 pcb.Height = 5 pcb.Placement = App.Placement(Vector(-(crucible_radius + 400) + 50, -50, 405), App.Rotation()) pcb.ViewObject.ShapeColor = (0.0, 0.5, 0.0) hs1 = doc.addObject("Part::Box", "Heatsink_1") hs1.Length = 80 hs1.Width = 40 hs1.Height = 50 hs1.Placement = App.Placement(Vector(-(crucible_radius + 400) + 60, -40, 410), App.Rotation()) hs1.ViewObject.ShapeColor = (0.1, 0.1, 0.1) hs2 = doc.addObject("Part::Box", "Heatsink_2") hs2.Length = 80 hs2.Width = 40 hs2.Height = 50 hs2.Placement = App.Placement(Vector(-(crucible_radius + 400) + 60, 50, 410), App.Rotation()) hs2.ViewObject.ShapeColor = (0.1, 0.1, 0.1) for i in range(3):
for j in range(2):
cap = doc.addObject("Part::Cylinder", f"Capacitor_{i}_{j}")
cap.Radius = 10
cap.Height = 30
cap.Placement = App.Placement(Vector(-(crucible_radius + 400) + 160 + (i*25), -20 + (j*25), 410), App.Rotation())
cap.ViewObject.ShapeColor = (0.8, 0.2, 0.2)
ind1 = doc.addObject("Part::Cylinder", "Choke_Inductor_1") ind1.Radius = 20 ind1.Height = 15 ind1.Placement = App.Placement(Vector(-(crucible_radius + 400) + 200, 60, 410), App.Rotation()) ind1.ViewObject.ShapeColor = (0.6, 0.4, 0.2)
- Bus Plates
plate1 = doc.addObject("Part::Box", "Bus_Plate_1") plate1.Length = 200 plate1.Width = 40 plate1.Height = 5 plate1.Placement = App.Placement(Vector(-(crucible_radius + 150), 0, 300), App.Rotation(Vector(0,1,0), -20)) plate1.ViewObject.ShapeColor = (0.8, 0.4, 0.0)
- Bus Bars
bar1 = doc.addObject("Part::Box", "Bus_Bar_1") bar1.Length = 200 bar1.Width = 20 bar1.Height = 100 bar1.Placement = App.Placement(Vector(-(crucible_radius + 100), 10, 100), App.Rotation()) bar1.ViewObject.ShapeColor = (0.8, 0.4, 0.0) bar2 = doc.addObject("Part::Box", "Bus_Bar_2") bar2.Length = 200 bar2.Width = 20 bar2.Height = 100 bar2.Placement = App.Placement(Vector(-(crucible_radius + 100), -30, 100), App.Rotation()) bar2.ViewObject.ShapeColor = (0.8, 0.4, 0.0)
- --- 6. Feeder ---
hopper = doc.addObject("Part::Cone", "Feeder_Hopper") hopper.Radius1 = 50 hopper.Radius2 = 150 hopper.Height = 200 hopper.Placement = App.Placement(Vector(0, 0, crucible_height + 150), App.Rotation()) hopper.ViewObject.ShapeColor = (0.6, 0.6, 0.7) beam = doc.addObject("Part::Box", "Feeder_Support") beam.Length = 40 beam.Width = 300 beam.Height = 40 beam.Placement = App.Placement(Vector(-(crucible_radius + 50), -150, crucible_height + 250), App.Rotation()) doc.recompute() home = os.path.expanduser("~") output_path = os.path.join(home, "Antigravity_24_Freecad", "outputs", "InductionFurnaceCore.FCStd") doc.saveAs(output_path) """
result = bridge.send_command({
"action": "execute_code",
"params": {
"code": code,
"description": "Create Induction Furnace Core"
}
})
print("Result:", result)
return result
</source>
Resources
- **Output Models:** `Antigravity_24_Freecad/outputs/InductionFurnace.FCStd`