Compare commits
1 Commits
ac73cfcf5e
...
real
| Author | SHA1 | Date | |
|---|---|---|---|
| e6ce15aee9 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
|||||||
__pycache__/
|
__pycache__
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ unit_x = np.array([1, 0, 0])
|
|||||||
unit_y = np.array([0, 1, 0])
|
unit_y = np.array([0, 1, 0])
|
||||||
unit_z = np.array([0, 0, 1])
|
unit_z = np.array([0, 0, 1])
|
||||||
|
|
||||||
|
|
||||||
def get_axis(axis):
|
def get_axis(axis):
|
||||||
"Axis are numbered from 1 to 3 from x to z."
|
"Axis are numbered from 1 to 3 from x to z."
|
||||||
match axis:
|
match axis:
|
||||||
@@ -18,11 +19,13 @@ def get_axis(axis):
|
|||||||
ax = unit_x
|
ax = unit_x
|
||||||
return ax
|
return ax
|
||||||
|
|
||||||
|
|
||||||
def proj(vec, axis: int = 1):
|
def proj(vec, axis: int = 1):
|
||||||
"""Simple vector projection onto an axis."""
|
"""Simple vector projection onto an axis."""
|
||||||
ax = get_axis(axis)
|
ax = get_axis(axis)
|
||||||
return np.dot(vec, ax) * ax
|
return np.dot(vec, ax) * ax
|
||||||
|
|
||||||
|
|
||||||
def rotate(v, angle=90, axis=1):
|
def rotate(v, angle=90, axis=1):
|
||||||
"Rotate a vector with an angle around a axis with the right hand rule."
|
"Rotate a vector with an angle around a axis with the right hand rule."
|
||||||
angle = angle / 180 * np.pi
|
angle = angle / 180 * np.pi
|
||||||
@@ -34,9 +37,15 @@ def rotate(v, angle=90, axis=1):
|
|||||||
+ k * np.dot(k, v) * (1 - np.cos(angle))
|
+ k * np.dot(k, v) * (1 - np.cos(angle))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def agl(a, b):
|
def agl(a, b):
|
||||||
"Get the angle between two vectors. This is always between 0 and 180 degree."
|
"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):
|
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.
|
"""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.
|
||||||
|
|||||||
9
helpers.py
Normal file
9
helpers.py
Normal 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}°"
|
||||||
|
)
|
||||||
@@ -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
|
import numpy as np
|
||||||
|
|
||||||
from objects.generic import Source, Target
|
from objects.generic import Source, Target
|
||||||
@@ -5,9 +10,10 @@ from objects.motor import Motor
|
|||||||
|
|
||||||
from calculator import get_angles
|
from calculator import get_angles
|
||||||
|
|
||||||
|
|
||||||
class Mirror:
|
class Mirror:
|
||||||
def __init__(self, world, cluster_x=0, cluster_y=0):
|
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_x = cluster_x
|
||||||
self.cluster_y = cluster_y
|
self.cluster_y = cluster_y
|
||||||
|
|
||||||
@@ -32,7 +38,7 @@ class Mirror:
|
|||||||
rel_source = source.pos - rot_pos
|
rel_source = source.pos - rot_pos
|
||||||
rel_target = target.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
|
# Update the angles based on the normals in rotated positions
|
||||||
self.motor_phi.set_angle(phi)
|
self.motor_phi.set_angle(phi)
|
||||||
|
|||||||
@@ -53,3 +53,4 @@ class World:
|
|||||||
y_rot = y
|
y_rot = y
|
||||||
z_rot = -x * sin_t + z * cos_t
|
z_rot = -x * sin_t + z * cos_t
|
||||||
return np.array([x_rot, y_rot, z_rot])
|
return np.array([x_rot, y_rot, z_rot])
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from helpers import print_status
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from objects.generic import Source, Target
|
from objects.generic import Source, Target
|
||||||
@@ -6,42 +7,21 @@ from objects.mirror import Mirror
|
|||||||
from objects.board import Board
|
from objects.board import Board
|
||||||
|
|
||||||
# Solar module for simulation of world
|
# Solar module for simulation of world
|
||||||
STEP = 10
|
|
||||||
LOOP_DELAY = 0.005 # In seconds
|
LOOP_DELAY = 0.005 # In seconds
|
||||||
|
|
||||||
# Testing embedding the mirrors in the world
|
# Testing embedding the mirrors in the world
|
||||||
board = Board()
|
board = Board()
|
||||||
world = World(board, tilt_deg=0)
|
world = World(board, tilt_deg=0)
|
||||||
|
|
||||||
HEIGHT = 30
|
|
||||||
|
|
||||||
source = Source(world, pos=(0, 50, 0))
|
source = Source(world, pos=(0, 50, 0))
|
||||||
target = Target(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 x in range(2):
|
||||||
for y in range(1):
|
for y in range(1):
|
||||||
mirror = Mirror(world, cluster_x=x, cluster_y=y)
|
mirror = Mirror(world, cluster_x=x, cluster_y=y)
|
||||||
world.add_mirror(mirror)
|
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
|
# Main
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
@@ -51,11 +31,9 @@ try:
|
|||||||
#print(target.pos)
|
#print(target.pos)
|
||||||
|
|
||||||
world.update_mirrors_from_source_target(source, target)
|
world.update_mirrors_from_source_target(source, target)
|
||||||
print_status()
|
print_status(world)
|
||||||
|
|
||||||
time.sleep(LOOP_DELAY)
|
time.sleep(LOOP_DELAY)
|
||||||
|
|
||||||
t = time.time()
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -516,7 +516,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solarmotor"
|
name = "solarmotor"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "adafruit-blinka" },
|
{ name = "adafruit-blinka" },
|
||||||
|
|||||||
Reference in New Issue
Block a user