feat: Major update with validators, skills, dashboard, and docs reorganization
- Add validation framework (config, model, results, study validators) - Add Claude Code skills (create-study, run-optimization, generate-report, troubleshoot, analyze-model) - Add Atomizer Dashboard (React frontend + FastAPI backend) - Reorganize docs into structured directories (00-09) - Add neural surrogate modules and training infrastructure - Add multi-objective optimization support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# NX File Modifications Required for Drone Gimbal Arm Study
|
||||
|
||||
## Overview
|
||||
|
||||
The study uses the same beam model as `simple_beam_optimization` but requires modifications to:
|
||||
1. Add modal analysis (frequency extraction)
|
||||
2. Update loading conditions for the 850g camera payload
|
||||
3. Ensure material properties match Al 7075-T6
|
||||
|
||||
## Critical Modifications
|
||||
|
||||
### 1. Simulation File (Beam_sim1.sim)
|
||||
|
||||
**REQUIRED: Add Modal Analysis Solution**
|
||||
|
||||
You need to add a **second solution** for modal analysis:
|
||||
|
||||
1. **Open** `Beam_sim1.sim` in NX Simcenter
|
||||
2. **Create New Solution**:
|
||||
- Solution Type: `SOL 103 - Normal Modes`
|
||||
- Name: `modal_analysis`
|
||||
- Number of modes: `10` (we only need the first, but calculate more for safety)
|
||||
- Frequency range: `0-500 Hz`
|
||||
|
||||
3. **Use Same Mesh** as the static solution
|
||||
- Link to existing FEM file: `Beam_fem1.fem`
|
||||
|
||||
4. **Boundary Conditions**: Use same constraints as static analysis
|
||||
- Fixed constraint at base (same as static)
|
||||
- No loads needed for modal (it finds natural frequencies)
|
||||
|
||||
### 2. Static Analysis Modifications
|
||||
|
||||
**Update Load Magnitude**:
|
||||
|
||||
The existing static analysis load needs to represent the **850g camera payload**:
|
||||
|
||||
1. **Open Solution 1** (static analysis)
|
||||
2. **Modify Force Magnitude**:
|
||||
- Old value: (whatever is currently there)
|
||||
- **New value**: `8.34 N` (850g × 9.81 m/s²)
|
||||
- Direction: Downward (negative Y or Z depending on your coordinate system)
|
||||
- Location: Tip of beam (where camera attaches)
|
||||
|
||||
Note: 120 MPa stress limit provides safety factor of 2.3 on 6061-T6 yield strength (276 MPa)
|
||||
|
||||
### 3. Material Properties
|
||||
|
||||
**Verify Material is Al 6061-T6**:
|
||||
|
||||
1. **Open Part File**: `Beam.prt`
|
||||
2. **Check Material Assignment**:
|
||||
- Material: `Aluminum 6061-T6`
|
||||
- Yield Strength: ~276 MPa
|
||||
- Young's Modulus: ~68.9 GPa
|
||||
- Density: ~2700 kg/m³
|
||||
- Poisson's Ratio: ~0.33
|
||||
|
||||
3. **If not Al 6061-T6**, update material assignment to match drone application requirements
|
||||
|
||||
### 4. Results Configuration
|
||||
|
||||
**Ensure these results are requested**:
|
||||
|
||||
**For Static Solution (Solution 1)**:
|
||||
- Displacement (VECTOR, all components)
|
||||
- von Mises Stress
|
||||
- Mass properties
|
||||
|
||||
**For Modal Solution (Solution 2)**:
|
||||
- Natural frequencies
|
||||
- Mode shapes (optional, for visualization)
|
||||
|
||||
## What You DON'T Need to Change
|
||||
|
||||
The parametric design variables are already set up correctly in the beam model:
|
||||
- `beam_half_core_thickness` (20-30mm)
|
||||
- `beam_face_thickness` (1-3mm)
|
||||
- `holes_diameter` (180-280mm)
|
||||
- `hole_count` (8-14)
|
||||
|
||||
These parameters will be automatically updated by the optimization loop.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Before running optimization, verify:
|
||||
|
||||
1. **Two Solutions Exist**:
|
||||
```
|
||||
Solution 1: Static Analysis (SOL 101) - displacement and stress
|
||||
Solution 2: Modal Analysis (SOL 103) - natural frequencies
|
||||
```
|
||||
|
||||
2. **Load is Correct**:
|
||||
- Static load = 8.34 N downward at tip
|
||||
|
||||
3. **Material is Al 7075-T6**
|
||||
|
||||
4. **Both solutions solve successfully** with baseline parameters:
|
||||
```
|
||||
beam_half_core_thickness = 25mm
|
||||
beam_face_thickness = 2mm
|
||||
holes_diameter = 230mm
|
||||
hole_count = 11
|
||||
```
|
||||
|
||||
## Quick Test
|
||||
|
||||
Run a manual solve with baseline parameters to verify:
|
||||
|
||||
Expected Results (approximate):
|
||||
- **Mass**: ~140-150g
|
||||
- **Max Displacement**: ~1-2 mm
|
||||
- **Max Stress**: ~80-100 MPa
|
||||
- **First Frequency**: ~120-140 Hz
|
||||
|
||||
If these are wildly different, check your setup.
|
||||
|
||||
## Extraction Configuration
|
||||
|
||||
The optimization engine will extract:
|
||||
- **Mass**: From Solution 1 mass properties
|
||||
- **Displacement**: Maximum displacement magnitude from Solution 1
|
||||
- **Stress**: Maximum von Mises stress from Solution 1
|
||||
- **Frequency**: First natural frequency (mode 1) from Solution 2
|
||||
|
||||
All extraction is automated - you just need to ensure the solutions are configured correctly.
|
||||
|
||||
## Optional Enhancements
|
||||
|
||||
If you want more realistic results:
|
||||
|
||||
1. **Add Gravity Load**:
|
||||
- Apply -9.81 m/s² gravity in addition to tip load
|
||||
- Represents arm's own weight during flight
|
||||
|
||||
2. **Add Damping** to modal analysis:
|
||||
- Structural damping ratio: ~0.02 (2%)
|
||||
- More realistic frequency response
|
||||
|
||||
3. **Refine Mesh** at stress concentrations:
|
||||
- Around holes
|
||||
- At base constraint
|
||||
- Better stress accuracy
|
||||
|
||||
But these are NOT required for the optimization to run successfully.
|
||||
193
studies/drone_gimbal_arm_optimization/README.md
Normal file
193
studies/drone_gimbal_arm_optimization/README.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Drone Camera Gimbal Support Arm Optimization
|
||||
|
||||
## Engineering Scenario
|
||||
|
||||
**Application**: Professional aerial cinematography drone
|
||||
**Component**: Camera gimbal support arm
|
||||
**Goal**: Lightweight design for extended flight time while maintaining camera stability
|
||||
|
||||
## Problem Statement
|
||||
|
||||
The current production arm weighs **145g** and meets all requirements. Marketing wants to advertise "30% longer flight time" by reducing weight. Your task: optimize the arm geometry to minimize weight while ensuring it doesn't compromise camera stability or structural integrity.
|
||||
|
||||
### Real-World Constraints
|
||||
|
||||
- **Camera Payload**: 850g (camera + gimbal mechanism)
|
||||
- **Maximum Deflection**: 1.5mm (required for image stabilization systems)
|
||||
- **Material**: Aluminum 6061-T6 (aerospace grade)
|
||||
- **Safety Factor**: 2.3 on yield strength (276 MPa)
|
||||
- **Vibration Avoidance**: Natural frequency must be > 150 Hz to avoid coupling with rotor frequencies (80-120 Hz)
|
||||
|
||||
## Multi-Objective Optimization
|
||||
|
||||
This study explores the **trade-off between two competing objectives**:
|
||||
|
||||
### Objectives
|
||||
1. **MINIMIZE Mass** - Every gram saved increases flight time
|
||||
- Target: < 120g (17% weight savings)
|
||||
- Current: 145g baseline
|
||||
|
||||
2. **MAXIMIZE Fundamental Frequency** - Higher frequency = better vibration isolation
|
||||
- Target: > 150 Hz (safety margin above 80-120 Hz rotor range)
|
||||
- Trade-off: Lighter designs typically have lower frequencies
|
||||
|
||||
### Constraints
|
||||
1. **Max Displacement** < 1.5mm under 850g load
|
||||
2. **Max von Mises Stress** < 120 MPa (Al 6061-T6 yield = 276 MPa, SF = 2.3)
|
||||
3. **Natural Frequency** > 150 Hz (hard requirement)
|
||||
|
||||
## Design Variables (Parametric Beam Model)
|
||||
|
||||
- **beam_half_core_thickness**: 20-30 mm (affects stiffness and weight)
|
||||
- **beam_face_thickness**: 1-3 mm (face sheets for bending resistance)
|
||||
- **holes_diameter**: 180-280 mm (lightening holes for weight reduction)
|
||||
- **hole_count**: 8-14 (number of lightening holes)
|
||||
|
||||
## Expected Outcomes
|
||||
|
||||
- **Pareto Front**: Shows designs on the optimal trade-off curve between mass and frequency
|
||||
- **Weight Savings**: 10-20% reduction from 145g baseline
|
||||
- **Constraint Analysis**: Clear visualization of which constraints are active/limiting
|
||||
- **Design Insights**: Understand how design variables affect both objectives
|
||||
|
||||
## Study Configuration
|
||||
|
||||
- **Protocol**: Protocol 11 (Multi-Objective Optimization)
|
||||
- **Sampler**: NSGA-II (genetic algorithm for Pareto fronts)
|
||||
- **Trials**: 30 (sufficient for Pareto front exploration)
|
||||
- **Duration**: ~1-2 hours (2-4 minutes per trial)
|
||||
|
||||
## Files in This Study
|
||||
|
||||
```
|
||||
drone_gimbal_arm_optimization/
|
||||
├── 1_setup/
|
||||
│ ├── model/
|
||||
│ │ ├── Beam.prt # Parametric beam geometry
|
||||
│ │ ├── Beam_sim1.sim # Simulation setup (needs modal analysis!)
|
||||
│ │ └── Beam_fem1.fem # Finite element mesh
|
||||
│ ├── optimization_config.json # Multi-objective config
|
||||
│ └── workflow_config.json # Extractor definitions
|
||||
├── 2_results/ # Created during optimization
|
||||
│ ├── study.db # Optuna database
|
||||
│ ├── optimization_history_incremental.json
|
||||
│ └── ...
|
||||
├── run_optimization.py # Main execution script
|
||||
├── NX_FILE_MODIFICATIONS_REQUIRED.md # IMPORTANT: Read this first!
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Before You Run
|
||||
|
||||
**CRITICAL**: You MUST modify the NX simulation files before running.
|
||||
|
||||
Read [NX_FILE_MODIFICATIONS_REQUIRED.md](NX_FILE_MODIFICATIONS_REQUIRED.md) for detailed instructions.
|
||||
|
||||
**Summary of Required Changes**:
|
||||
1. Add **Modal Analysis Solution** (SOL 103) to extract natural frequencies
|
||||
2. Update **static load** to 8.34 N (850g camera payload)
|
||||
3. Verify **material** is Al 7075-T6
|
||||
|
||||
## Running the Optimization
|
||||
|
||||
```bash
|
||||
# Quick test (5 trials, ~10-20 minutes)
|
||||
cd studies/drone_gimbal_arm_optimization
|
||||
python run_optimization.py --trials 5
|
||||
|
||||
# Full study (30 trials, ~1-2 hours)
|
||||
python run_optimization.py --trials 30
|
||||
|
||||
# Resume existing study
|
||||
python run_optimization.py --resume
|
||||
```
|
||||
|
||||
## Monitoring in Dashboard
|
||||
|
||||
While optimization runs, monitor in real-time:
|
||||
|
||||
1. **Start Dashboard Backend** (separate terminal):
|
||||
```bash
|
||||
cd atomizer-dashboard/backend
|
||||
python -m uvicorn api.main:app --reload --port 8000
|
||||
```
|
||||
|
||||
2. **Start Dashboard Frontend** (another terminal):
|
||||
```bash
|
||||
cd atomizer-dashboard/frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
3. **Open Browser**: http://localhost:3003
|
||||
|
||||
4. **Select Study**: drone_gimbal_arm_optimization
|
||||
|
||||
### Dashboard Features You'll See
|
||||
|
||||
- **Real-time trial updates** via WebSocket
|
||||
- **Pareto front visualization** (mass vs frequency scatter plot)
|
||||
- **Constraint violation tracking** (which trials failed which constraints)
|
||||
- **Progress monitoring** (30 trials total)
|
||||
- **New best notifications** when Pareto front expands
|
||||
|
||||
## Interpreting Results
|
||||
|
||||
### Pareto Front Analysis
|
||||
|
||||
The Pareto front will show:
|
||||
- **Lower-left designs**: Lighter but lower frequency (more prone to vibration)
|
||||
- **Upper-right designs**: Heavier but higher frequency (better vibration isolation)
|
||||
- **Middle region**: Balanced trade-offs
|
||||
|
||||
### Selecting Final Design
|
||||
|
||||
Choose based on flight profile:
|
||||
- **Stable hovering flights**: Select lighter design (mass priority)
|
||||
- **Dynamic maneuvers**: Select higher frequency design (vibration priority)
|
||||
- **Balanced missions**: Mid-Pareto design
|
||||
|
||||
### Constraint Active Check
|
||||
|
||||
Look for designs where:
|
||||
- Displacement constraint is just satisfied (1.4-1.5mm) = efficient use of deflection budget
|
||||
- Frequency constraint is marginally above 150 Hz = not over-designed
|
||||
- Stress well below limit = safety margin confirmed
|
||||
|
||||
## Why This is Realistic
|
||||
|
||||
This scenario reflects real engineering trade-offs in aerospace:
|
||||
|
||||
1. **Weight vs Performance**: Classic aerospace dilemma
|
||||
2. **Multi-Physics Constraints**: Static strength + dynamic vibration
|
||||
3. **Safety Margins**: Realistic stress limits with safety factors
|
||||
4. **Operational Requirements**: Specific to drone camera applications
|
||||
5. **Pareto Decision-Making**: No single "best" design, requires engineering judgment
|
||||
|
||||
## Comparison with Bracket Study
|
||||
|
||||
Unlike the bracket study (single objective), this study shows:
|
||||
- **Multiple optimal solutions** (Pareto set, not single optimum)
|
||||
- **Trade-off visualization** (can't optimize both objectives simultaneously)
|
||||
- **Richer decision support** (choose based on priorities)
|
||||
- **More complex analysis** (static + modal)
|
||||
|
||||
## Next Steps After Optimization
|
||||
|
||||
1. **Review Pareto front** in dashboard
|
||||
2. **Select 2-3 candidate designs** from different regions of Pareto front
|
||||
3. **Detailed FEA verification** of selected candidates
|
||||
4. **Fatigue analysis** for repeated flight cycles
|
||||
5. **Prototype testing** to validate predictions
|
||||
6. **Down-select** based on test results
|
||||
|
||||
## Technical Notes
|
||||
|
||||
- Uses **NSGA-II** multi-objective optimizer (Optuna)
|
||||
- Handles **3 constraints** with penalty methods
|
||||
- Extracts **4 quantities** from 2 different solutions (static + modal)
|
||||
- Fully automated - no manual intervention during run
|
||||
- Results compatible with all dashboard visualization features
|
||||
|
||||
## Questions?
|
||||
|
||||
This study demonstrates the full power of multi-objective optimization for real engineering problems. The Pareto front provides engineering insights that single-objective optimization cannot offer.
|
||||
16
studies/drone_gimbal_arm_optimization/reset_study.py
Normal file
16
studies/drone_gimbal_arm_optimization/reset_study.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""Reset drone gimbal arm optimization study by deleting database."""
|
||||
import optuna
|
||||
from pathlib import Path
|
||||
|
||||
study_dir = Path(__file__).parent
|
||||
storage = f"sqlite:///{study_dir / '2_results' / 'study.db'}"
|
||||
study_name = "drone_gimbal_arm_optimization"
|
||||
|
||||
try:
|
||||
# Delete the study
|
||||
optuna.delete_study(study_name=study_name, storage=storage)
|
||||
print(f"[OK] Deleted study: {study_name}")
|
||||
except KeyError:
|
||||
print(f"[WARNING] Study '{study_name}' not found (database may not exist)")
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Error: {e}")
|
||||
Reference in New Issue
Block a user