Formatting

This commit is contained in:
2026-01-15 18:36:56 +01:00
parent ac73cfcf5e
commit e6ce15aee9
7 changed files with 43 additions and 40 deletions

2
.gitignore vendored
View File

@@ -1 +1 @@
__pycache__/
__pycache__

View File

@@ -5,6 +5,7 @@ unit_x = np.array([1, 0, 0])
unit_y = np.array([0, 1, 0])
unit_z = np.array([0, 0, 1])
def get_axis(axis):
"Axis are numbered from 1 to 3 from x to z."
match axis:
@@ -18,14 +19,16 @@ def get_axis(axis):
ax = unit_x
return ax
def proj(vec, axis: int =1):
def proj(vec, axis: int = 1):
"""Simple vector projection onto an axis."""
ax = get_axis(axis)
return np.dot(vec, ax) * ax
def rotate(v, angle=90, axis=1):
"Rotate a vector with an angle around a axis with the right hand rule."
angle = angle/180 * np.pi
angle = angle / 180 * np.pi
k = get_axis(axis)
return (
@@ -34,9 +37,15 @@ def rotate(v, angle=90, axis=1):
+ k * np.dot(k, v) * (1 - np.cos(angle))
)
def agl(a, b):
"Get the angle between two vectors. This is always between 0 and 180 degree."
return np.round(np.acos(np.dot(a, b)/(np.linalg.norm(a) * np.linalg.norm(b)))/(2 * np.pi) * 360)
return np.round(
np.acos(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
/ (2 * np.pi)
* 360
)
def get_angles(source, target):
"""Main function to get the phi and theta angles for a source and a target vector. Both vectors must lie on the front half sphere.
@@ -59,15 +68,15 @@ def get_angles(source, target):
if source_phi < target_phi:
rota = rotate(source_planar, phi_diff, 3)
theta_diff = agl(rota, target)
phi = source_phi + phi_diff/2
phi = source_phi + phi_diff / 2
else:
rota = rotate(target_planar, phi_diff, 3)
theta_diff = agl(rota, source)
phi = target_phi + phi_diff/2
phi = target_phi + phi_diff / 2
if source_theta < target_theta:
theta = target_theta + theta_diff/2
theta = target_theta + theta_diff / 2
else:
theta = source_theta + theta_diff/2
theta = source_theta + theta_diff / 2
return (phi, theta)

9
helpers.py Normal file
View File

@@ -0,0 +1,9 @@
from objects.world import World
def print_status(world: World):
for i, mirror in enumerate(world.mirrors):
phi, theta = mirror.get_angles()
print(
f"Mirror {i} ({mirror.cluster_x}, {mirror.cluster_y}) angles -> phi: {phi:.2f}°, theta: {theta:.2f}°"
)

View File

@@ -1,3 +1,8 @@
"""
When theta motor is at 0 then mirror is up and when at 180 then mirror is front.
Phi 0 equals right and phi 180 equals left by 45 degrees.
"""
import numpy as np
from objects.generic import Source, Target
@@ -5,9 +10,10 @@ from objects.motor import Motor
from calculator import get_angles
class Mirror:
def __init__(self, world, cluster_x=0, cluster_y=0):
self.world = world
self.world = world # TODO: Fix this cyclic reference
self.cluster_x = cluster_x
self.cluster_y = cluster_y
@@ -32,7 +38,7 @@ class Mirror:
rel_source = source.pos - rot_pos
rel_target = target.pos - rot_pos
phi, theta = get_angles(rel_source, rel_target) # ty:ignore[unresolved-reference]
phi, theta = get_angles(rel_source, rel_target)
# Update the angles based on the normals in rotated positions
self.motor_phi.set_angle(phi)

View File

@@ -53,3 +53,4 @@ class World:
y_rot = y
z_rot = -x * sin_t + z * cos_t
return np.array([x_rot, y_rot, z_rot])

View File

@@ -1,3 +1,4 @@
from helpers import print_status
import time
from objects.generic import Source, Target
@@ -6,42 +7,21 @@ from objects.mirror import Mirror
from objects.board import Board
# Solar module for simulation of world
STEP = 10
LOOP_DELAY = 0.005 # In seconds
# Testing embedding the mirrors in the world
board = Board()
world = World(board, tilt_deg=0)
HEIGHT = 30
source = Source(world, pos=(0, 50, 0))
target = Target(world, pos=(0, 50, 0))
# Create mirrors in a 3x2 grid
# Create mirrors in a grid
for x in range(2):
for y in range(1):
mirror = Mirror(world, cluster_x=x, cluster_y=y)
world.add_mirror(mirror)
world.update_mirrors_from_source_target(source, target)
def print_status():
for i, mirror in enumerate(world.mirrors):
phi, theta = mirror.get_angles()
print(f"Mirror {i} ({mirror.cluster_x}, {mirror.cluster_y}) angles -> phi: {phi:.2f}°, theta: {theta:.2f}°")
a = 1
t = time.time()
world.mirrors[0].motor_theta.set_angle(180)
world.mirrors[0].motor_phi.set_angle(180)
world.mirrors[1].motor_phi.set_angle(0)
world.mirrors[1].motor_theta.set_angle(0)
print_status()
# Main
try:
while True:
@@ -51,11 +31,9 @@ try:
#print(target.pos)
world.update_mirrors_from_source_target(source, target)
print_status()
print_status(world)
time.sleep(LOOP_DELAY)
t = time.time()
except KeyboardInterrupt:
pass

2
uv.lock generated
View File

@@ -516,7 +516,7 @@ wheels = [
[[package]]
name = "solarmotor"
version = "0.1.0"
version = "0.1.1"
source = { virtual = "." }
dependencies = [
{ name = "adafruit-blinka" },