|
45 | 45 |
|
46 | 46 | # Configuration |
47 | 47 | # Scaling (pixels to degrees) |
48 | | -PIXEL_SCALE = -0.3 |
| 48 | +# FOV 72 degrees over 240 pixels: |
| 49 | +PIXEL_SCALE = -72.0/240 |
49 | 50 | HALF_IMAGE_WIDTH = const(120) |
50 | 51 |
|
51 | | - |
52 | 52 | # Pin usage (change as necessary) |
53 | 53 | TX_PIN = board.TX |
54 | 54 | RX_PIN = board.RX |
55 | 55 | SERVO_PWM_PIN = board.D0 |
56 | 56 | LED_PIN = board.D1 # active low |
57 | 57 |
|
58 | | -SMOOTH_ALPHA = const(0.25) |
| 58 | +SMOOTH_ALPHA = const(0.4) # lower=slower |
59 | 59 |
|
60 | 60 | # Globals |
61 | 61 | now = time.monotonic # cached |
62 | 62 | ai = ATDevice(TX_PIN, RX_PIN) |
63 | 63 | pwm = pwmio.PWMOut(SERVO_PWM_PIN, duty_cycle=2**15, frequency=50) |
64 | 64 | motor = servo.Servo(pwm) |
65 | 65 | led = DigitalInOut(LED_PIN) |
66 | | -led.switch_to_output(value=True) |
67 | | -target_angle = 90 |
68 | | -motor.angle = target_angle # [0..180] |
69 | 66 |
|
70 | 67 |
|
71 | 68 | class Smoother: |
@@ -95,7 +92,7 @@ def update(self, new_value: float) -> float: |
95 | 92 | return self.value |
96 | 93 |
|
97 | 94 |
|
98 | | -smoothed_angle = Smoother(target_angle, SMOOTH_ALPHA) |
| 95 | +smoothed_angle = Smoother(90, SMOOTH_ALPHA) |
99 | 96 |
|
100 | 97 |
|
101 | 98 | def enable_led(value: bool) -> None: |
@@ -162,28 +159,35 @@ def get_best_box_angle(boxes: list[Box]) -> float | None: |
162 | 159 | # print(f"id={ai.id()}") |
163 | 160 | # print(f"name={ai.name()}") |
164 | 161 |
|
165 | | -while True: |
166 | | - try: |
167 | | - started = now() |
168 | | - err = ai.invoke(1, True, True) |
169 | | - duration = int((now() - started) * 1000) |
170 | | - if err != CMD_OK: |
171 | | - enable_led(False) |
172 | | - print(f"{duration} No response") |
173 | | - set_motor(target_angle) |
174 | | - continue |
175 | | - best_angle = get_best_box_angle(ai.boxes) |
176 | | - if best_angle is not None: |
177 | | - enable_led(True) |
178 | | - target_angle = best_angle |
179 | | - print(f"{duration} Boxes: {ai.boxes}, Perf: {ai.perf}") |
180 | | - set_motor(best_angle) |
181 | | - else: |
182 | | - enable_led(False) |
183 | | - print(f"{duration} No boxes") |
184 | | - set_motor(target_angle) |
185 | | - except ValueError as e: |
186 | | - print(e) |
187 | | - except KeyboardInterrupt: |
188 | | - motor.angle = 90 |
189 | | - break |
| 162 | + |
| 163 | +def run(): |
| 164 | + led.switch_to_output(value=True) |
| 165 | + target_angle = motor.angle = 90 |
| 166 | + |
| 167 | + while True: |
| 168 | + try: |
| 169 | + started = now() |
| 170 | + err = ai.invoke(1, True, True) |
| 171 | + duration = int((now() - started) * 1000) |
| 172 | + if err != CMD_OK: |
| 173 | + enable_led(False) |
| 174 | + print(f"{duration} No response") |
| 175 | + else: |
| 176 | + best_angle = get_best_box_angle(ai.boxes) |
| 177 | + if best_angle is not None: |
| 178 | + enable_led(True) |
| 179 | + target_angle = best_angle |
| 180 | + print(f"{duration} Boxes: {ai.boxes}, Perf: {ai.perf}") |
| 181 | + else: |
| 182 | + enable_led(False) |
| 183 | + print(f"{duration} No boxes") |
| 184 | + except ValueError as e: |
| 185 | + print(e) |
| 186 | + except KeyboardInterrupt: |
| 187 | + target_angle = motor.angle = 90 |
| 188 | + break |
| 189 | + |
| 190 | + set_motor(target_angle) |
| 191 | + |
| 192 | + |
| 193 | +run() |
0 commit comments