diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/motor.py b/motor.py index 9978c20..abcbb88 100644 --- a/motor.py +++ b/motor.py @@ -3,6 +3,9 @@ import RPi.GPIO as GPIO import time import os +# Solar module for simulation of world +import solar + # Constants SERVO1_PIN = 18 SERVO2_PIN = 19 @@ -13,9 +16,9 @@ BUTTON2_FWD = 17 BUTTON2_BWD = 27 SHUTDOWN_BTN = 26 -MIN_PULSE = 1000 # In ms -MAX_PULSE = 2000 -INIT_PULSE = 1500 +MIN_PULSE = 500 # In ms +MAX_PULSE = 2500 +INIT_PULSE = 1000 STEP = 10 LOOP_DELAY = 0.01 # In seconds @@ -42,6 +45,24 @@ def move_servo(current, target, step=STEP): current = max(current - step, target) return current +# Testing embedding the mirrors in the world +world = solar.World(tilt_deg=15) # The world is tilted 15 degrees around y-axis + +source = solar.Source(world, pos=(100, 100, 100)) +target = solar.Target(world, pos=(50, 50, 0)) + +# Create mirrors in a 9x9 grid +for x in range(3): + for y in range(3): + mirror = solar.Mirror(world, cluster_x=x, cluster_y=y) + world.add_mirror(mirror) + +world.update_mirrors_from_source_target(source, target) + +for i, mirror in enumerate(world.mirrors): + pitch, yaw = mirror.get_angles() + print(f"Mirror {i} ({mirror.cluster_x}, {mirror.cluster_y}) angles -> pitch: {pitch:.2f}°, yaw: {yaw:.2f}°") + # Main try: while True: diff --git a/solar.py b/solar.py new file mode 100644 index 0000000..d77166c --- /dev/null +++ b/solar.py @@ -0,0 +1,105 @@ +"""Alle gemessenen Koordinaten der Quelle und der Sonne haben den Ursprung in der linken unteren Ecke des Clusters in einem rechtshaendigen flachen System. +""" + +import math + +class MovingEntity: + """Embedded entity in the world with a position.""" + + def __init__(self, world): + self.world = world + self.pos = (0.0, 0.0, 0.0) # (x, y, z) in local untilted coordinates + + def get_pos_rotated(self): + """Return position rotated by world's tilt around y-axis.""" + return self.world.rotate_point_y(self.pos) + +class Target(MovingEntity): + def __init__(self, world, pos=(0.0, 0.0, 0.0)): + super().__init__(world) + self.pos = pos + +class Source(MovingEntity): + def __init__(self, world, pos=(10.0, 10.0, 10.0)): + super().__init__(world) + self.pos = pos + +class Mirror: + def __init__(self, world, cluster_x=0, cluster_y=0): + self.world = world + self.cluster_x = cluster_x + self.cluster_y = cluster_y + self.angle_x = 0.0 + self.angle_y = 0.0 + + # Position in un-tilted coordinate system + self.pos = (cluster_x * self.world.grid_size, + cluster_y * self.world.grid_size, + 0.0) + + def get_pos_rotated(self): + return self.world.rotate_point_y(self.pos) + + def set_angle_from_source_target(self, source: Source, target: Target): + # Get rotated positions + pos_mirror = self.get_pos_rotated() + pos_source = source.get_pos_rotated() + pos_target = target.get_pos_rotated() + + v_source = ( + pos_source[0] - pos_mirror[0], + pos_source[1] - pos_mirror[1], + pos_source[2] - pos_mirror[2], + ) + v_target = ( + pos_target[0] - pos_mirror[0], + pos_target[1] - pos_mirror[1], + pos_target[2] - pos_mirror[2], + ) + + def normalize(v): + length = math.sqrt(v[0] ** 2 + v[1] ** 2 + v[2] ** 2) + if length == 0: + return (0, 0, 0) + return (v[0] / length, v[1] / length, v[2] / length) + + v_source_n = normalize(v_source) + v_target_n = normalize(v_target) + + mirror_normal = ( + v_source_n[0] + v_target_n[0], + v_source_n[1] + v_target_n[1], + v_source_n[2] + v_target_n[2], + ) + mirror_normal = normalize(mirror_normal) + + # Update the angles based on the normals in rotated positions + self.angle_y = math.degrees(math.atan2(mirror_normal[0], mirror_normal[2])) + self.angle_x = math.degrees(math.atan2(mirror_normal[1], mirror_normal[2])) + + def get_angles(self): + return self.angle_x, self.angle_y + +class World: + def __init__(self, tilt_deg=0.0): + self.grid_size = 10 # In cm + self.tilt_deg = tilt_deg # Tilt of the grid system around y-axis + self.mirrors = [] + + def add_mirror(self, mirror): + self.mirrors.append(mirror) + + def update_mirrors_from_source_target(self, source: Source, target: Target): + for mirror in self.mirrors: + mirror.set_angle_from_source_target(source, target) + + def rotate_point_y(self, point): + """Rotate a point around the y-axis by the world's tilt angle.""" + x, y, z = point + theta = math.radians(self.tilt_deg) + cos_t = math.cos(theta) + sin_t = math.sin(theta) + x_rot = x * cos_t + z * sin_t + y_rot = y + z_rot = -x * sin_t + z * cos_t + return (x_rot, y_rot, z_rot)