Optimierung von LEDs für ein gleichmäßiges Licht auf der OberflächePython

Python-Programme
Anonymous
 Optimierung von LEDs für ein gleichmäßiges Licht auf der Oberfläche

Post by Anonymous »

Ich habe dieses Problem, in dem ich ein LED -Muster so erstellen möchte, dass das gleichmäßigste Licht in einem Bereich in einer Ebene 5 cm entfernt wird. Ich kann die Leistung der LEDs nicht einzeln ändern und ich kann das Strahlungsmuster der LEDs nicht ändern. Ich kann also lediglich die LEDs innerhalb einer Fläche von 40 × 40 cm verteilen, um die gleichmäßigste Verteilung innerhalb eines Bereichs von 20 × 20 cm 5 cm von der LED -Ebene entfernt zu erreichen. Ich habe verschiedene Methoden ausprobiert, aber noch keinen guten Weg gefunden. Das Bild ist das Bild unten, aber das war nicht mit meinem wirklichen Strahlungsmuster. Ich möchte zwischen 100 bis 200 LEDs verwenden, was es auch zu einem ziemlich rechnerischen Problem macht, zumindest mit den Dingen, die ich ausprobiert habe. Es ist auch eine Anforderung, dass die LEDs mit einem Mindestabstand von 1 cm beabstandet sind. Ich denke, es gibt viel aus Symmetrie zu gewinnen, konnte aber keinen guten Weg finden, dies zu implementieren. Weiß jemand davon, dass dies woanders gelöst wurde oder eine gute Idee dafür hat?

Code: Select all

import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt

class SimpleRadiationPattern:
"""A simple Lambertian radiation pattern for LED illumination."""

def get_intensity_factor(self, cos_theta):
"""Return the relative intensity factor based on angle cosine."""
# Lambertian pattern: intensity proportional to cosine of the angle
if isinstance(cos_theta, np.ndarray):
return np.maximum(0, cos_theta)
else:
return max(0, cos_theta)

class LEDOptimizer:
def __init__(self, grid_size=0.2, grid_resolution=50, target_area_size=0.1, z_distance=0.05):
"""Initialize the LED optimization system."""
self.grid_size = grid_size  # Size of the entire simulation area (meters)
self.grid_resolution = grid_resolution  # Number of grid points
self.target_area_size = target_area_size  # Size of target area (meters)
self.z_distance = z_distance  # Distance from LED plane to target plane
self.radiation_pattern = SimpleRadiationPattern()

# Create the grid
self.x = np.linspace(-grid_size/2, grid_size/2, grid_resolution)
self.y = np.linspace(-grid_size/2, grid_size/2, grid_resolution)
self.X, self.Y = np.meshgrid(self.x, self.y)

# Define the target area (square region where we want uniform illumination)
self.target_mask = (
(self.X >= -target_area_size/2) &
(self.X = -target_area_size/2) &
(self.Y   0:
non_uniformity = std_dev_illuminance / mean_illuminance
else:
non_uniformity = float('inf')  # Avoid division by zero

return non_uniformity

def optimize_led_positions(self, n_leds, max_iterations=100, convergence_threshold=0.001, patience=10):
"""
Optimize the positions of n_leds to achieve uniform illumination.

Parameters:
- n_leds: Number of LEDs to place
- max_iterations: Maximum number of optimization iterations
- convergence_threshold: If relative improvement is less than this for 'patience' iterations, stop
- patience: Number of consecutive iterations with minimal improvement before stopping

Returns:
- optimal_positions: Array of shape (n_leds, 2) with optimized positions
- uniformity_score: Final uniformity score (lower is better)
"""
# Initialize history for convergence tracking
self.convergence_history = []

# Track consecutive iterations with minimal improvement
stagnant_iterations = 0

# Initial guess: place LEDs in a grid around the target area
grid_side = int(np.ceil(np.sqrt(n_leds)))
spacing = self.target_area_size * 1.5 / (grid_side - 1) if grid_side > 1 else 0

initial_positions = []
for i in range(grid_side):
for j in range(grid_side):
if len(initial_positions) < n_leds:
x = -self.target_area_size * 0.75 + i * spacing
y = -self.target_area_size * 0.75 + j * spacing
initial_positions.append([x, y])

initial_positions = np.array(initial_positions).flatten()

# Define bounds for the LED positions
bounds = []
for _ in range(n_leds):
bounds.extend([
(-self.grid_size/2, self.grid_size/2),  # x bounds
(-self.grid_size/2, self.grid_size/2)   # y bounds
])

# Initial score for starting point
initial_score = self.evaluate_uniformity(initial_positions)
self.convergence_history.append(initial_score)
previous_score = initial_score
print(f"Initial uniformity score: {initial_score:.6f}")

# Define callback function to track progress and implement early stopping
def callback(xk):
nonlocal stagnant_iterations, previous_score

score = self.evaluate_uniformity(xk)
self.convergence_history.append(score)

# Calculate relative improvement
if previous_score > 0:
rel_improvement = (previous_score - score) / previous_score
else:
rel_improvement = 0

# Check for convergence
if rel_improvement <  convergence_threshold:
stagnant_iterations += 1
else:
stagnant_iterations = 0

previous_score = score

# Print status every 10 iterations
if len(self.convergence_history) % 10 == 0:
print(f"Iteration {len(self.convergence_history)-1}: Score = {score:.6f}")

# Stop if we've had too many iterations with minimal improvement
if stagnant_iterations >= patience:
print(f"Stopping early - minimal improvement for {patience} consecutive iterations")
return True

return False

# Run the optimization
result = minimize(
self.evaluate_uniformity,
initial_positions,
method='L-BFGS-B',
bounds=bounds,
options={'maxiter': max_iterations},
callback=callback
)

# Reshape the result back to (n_leds, 2)
optimal_positions = result.x.reshape(-1, 2)

# Calculate the final uniformity score
uniformity_score = self.evaluate_uniformity(result.x)

print(f"Optimization complete: Final score = {uniformity_score:.6f}")
print(f"Improvement: {(initial_score - uniformity_score) / initial_score * 100:.2f}%")

return optimal_positions, uniformity_score

def plot_illuminance(self, led_positions, title="LED Illuminance Distribution"):
"""Plot the illuminance distribution with the given LED positions."""
# Calculate the illuminance
total_illuminance = self.calculate_illuminance(led_positions)

# Create the figure
plt.figure(figsize=(10, 8))

# Plot the illuminance heatmap
plt.pcolormesh(self.X, self.Y, total_illuminance, cmap='viridis', shading='auto')
plt.colorbar(label='Relative Illuminance')
plt.xlabel('X (meters)')
plt.ylabel('Y (meters)')

# Mark the target area boundary
target_x = self.target_area_size / 2
target_y = self.target_area_size / 2
plt.plot(
[-target_x, target_x, target_x, -target_x, -target_x],
[-target_y, -target_y, target_y, target_y, -target_y],
'r--', linewidth=2, label='Target Area'
)

# Mark the LED positions
plt.scatter(led_positions[:, 0], led_positions[:, 1],
color='red', marker='x', s=50, label='LEDs')

plt.title(title)
plt.legend()
plt.axis('equal')
plt.tight_layout()
plt.show()

# Example usage
if __name__ == "__main__":
# Create an optimizer instance
optimizer = LEDOptimizer(
grid_size=0.2,          # 20cm x 20cm simulation area
grid_resolution=50,     # 50x50 grid points for faster calculation
target_area_size=0.1,   # 10cm x 10cm target area
z_distance=0.05         # 5cm distance from LEDs to target
)

# Optimize positions for 4 LEDs
n_leds = 40
optimal_positions, score = optimizer.optimize_led_positions(
n_leds,
max_iterations=100,
convergence_threshold=0.001,
patience=10
)

# Plot the results
optimizer.plot_illuminance(optimal_positions, title=f"Optimal {n_leds} LED Configuration")

# Print optimized LED positions
print("\nOptimized LED positions:")
for i, pos in enumerate(optimal_positions):
print(f"LED {i+1}: ({pos[0]:.4f}, {pos[1]:.4f})")

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post