Untitled
def animate(self): if self._destroyed: return current_time = time.time() # Update can_press status if not self.can_press and current_time - self.last_press_time >= self.cooldown_period: self.can_press = True # Handle fill level animation if self.target_fill_level != self.fill_level: diff = self.target_fill_level - self.fill_level self.fill_level += diff * 0.2 if abs(diff) < 0.5: self.fill_level = self.target_fill_level # Handle press animation if self.press_animation_active: if self.is_pressed: self.press_scale = max(self.PRESS_SCALE_MIN, self.press_scale - self.SCALE_STEP) if self.press_scale == self.PRESS_SCALE_MIN: self.press_animation_active = self.is_pressed else: self.press_scale = min(self.PRESS_SCALE_MAX, self.press_scale + self.SCALE_STEP) if self.press_scale == self.PRESS_SCALE_MAX: self.press_animation_active = False # Handle pulse animation during servo active state if self.servo_active: if self.pulse_growing: self.pulse_scale = min(self.PULSE_MAX, self.pulse_scale + self.PULSE_STEP) if self.pulse_scale >= self.PULSE_MAX: self.pulse_growing = False else: self.pulse_scale = max(self.PULSE_MIN, self.pulse_scale - self.PULSE_STEP) if self.pulse_scale <= self.PULSE_MIN: self.pulse_growing = True else: self.pulse_scale = 1.0 # Apply combined scale final_scale = self.press_scale * self.pulse_scale # Only redraw if there's been a change if self.press_animation_active or self.servo_active or self.target_fill_level != self.fill_level: self.draw(scale=final_scale) self.after(16, self.animate) # ~60 FPS def handle_manual_fill(self): """Handle manual filling of the bin with improved feedback""" # Find turntable controller turntable = None root = self.winfo_toplevel() for widget in root.winfo_children(): if isinstance(widget, ctk.CTkFrame): for child in widget.winfo_children(): if isinstance(child, ClassificationPrompt): turntable = child.turntable break if turntable: break if not turntable or not turntable.is_initialized: return # Check if any other bin is currently active for instance in self._instances: if instance != self and instance.servo_active: return # Prevent activation if another bin is active if self.servo_active: # If servo is already open, close it self.close_servo(turntable) else: # Start the filling process self.start_filling_process(turntable) def start_filling_process(self, turntable): """Start the bin filling process with visual feedback""" try: # Move to bin position target_position = turntable.positions[self.bin_id] steps, direction = turntable._calculate_steps(target_position) turntable._move_motor(steps, direction) turntable.current_position = target_position # Open servo and start visual feedback if hasattr(turntable, 'hardware'): turntable.hardware.servo_motor.angle = 90 self.servo_active = True self.servo_start_time = time.time() # Start auto-close timer self.servo_timer = self.after( int(self.SERVO_OPEN_TIME * 1000), lambda: self.close_servo(turntable) ) except Exception as e: print(f"Error in fill process: {e}") self.close_servo(turntable) def close_servo(self, turntable): """Close the servo and update fill level""" try: # Cancel any pending timer if hasattr(self, 'servo_timer'): self.after_cancel(self.servo_timer) self.servo_timer = None # Close servo if hasattr(turntable, 'hardware'): turntable.hardware.servo_motor.angle = 0 self.servo_active = False # Wait for contents to settle time.sleep(0.5) # Measure fill level readings = turntable.hardware.get_measurements() closest_reading, percentage = turntable.hardware.process_readings(readings) if percentage is not None: turntable.hardware.update_fill_level(self.bin_id, percentage) self.set_fill_level(percentage) CircularProgress.update_all_instances() except Exception as e: print(f"Error closing servo: {e}") # Ensure servo is closed on error try: if hasattr(turntable, 'hardware'): turntable.hardware.servo_motor.angle = 0 self.servo_active = False except: pass def on_press(self, event): # First check if settings menu is open root = self.winfo_toplevel() for widget in root.winfo_children(): if isinstance(widget, ctk.CTkFrame): for child in widget.winfo_children(): if isinstance(child, SettingsMenu) and child.is_open: return # Check if this instance is in reset mode if hasattr(self, 'is_reset_mode') and self.is_reset_mode: return current_time = time.time() if current_time - self.last_press_time >= self.cooldown_period and self.can_press: self.is_pressed = True self.press_animation_active = True self.last_press_time = current_time self.can_press = False # Handle manual fill behavior self.handle_manual_fill()
Leave a Comment