diff --git a/hardware_interface.py b/hardware_interface.py new file mode 100644 index 0000000000000000000000000000000000000000..912b99635d95e9c83ceae9fc3e32e56b1d22bb4a --- /dev/null +++ b/hardware_interface.py @@ -0,0 +1,134 @@ +class HardwareInterface: + def __init__(self, hardware_params): + """ + Initialize hardware interface components. + - Setup GPIO pins for motor control and rotary encoder. + - Initialize variables for motor control and angle measurement. + """ + # Initialize motor control pins (GPIO setup) + self.motor_pin_in1 = hardware_params['motor_pins'][0] + self.motor_pin_in2 = hardware_params['motor_pins'][1] + + # Initialize rotary encoder pins (GPIO setup) + self.encoder_pin_clk = hardware_params['encoder_pins'][0] + self.encoder_pin_dt = hardware_params['encoder_pins'][1] + + # Setup initial states and values for motor control and angle measurement + self.angle = 0 + self.last_state_clk = self.read_encoder_pin(self.encoder_pin_clk) + + # Define motor control parameters (e.g., speed, direction) + self.motor_speed = 0 + + def read_encoder_pin(self, pin): + """ + Read the state of the rotary encoder pin. + - Implement debouncing logic if necessary. + - Return the current state of the pin. + """ + # Implement GPIO read functionality + return gpio_read(pin) + + def update_angle(self): + """ + Update the angle of the pole based on rotary encoder inputs. + - Read the current state of the encoder. + - Compare it with the last state to detect rotation direction. + - Increment or decrement the angle based on direction. + """ + current_state_clk = self.read_encoder_pin(self.encoder_pin_clk) + + if current_state_clk != self.last_state_clk: + # Check rotation direction + if self.read_encoder_pin(self.encoder_pin_dt) != current_state_clk: + self.angle += 1 # Clockwise rotation + else: + self.angle -= 1 # Counter-clockwise rotation + + # Update last state + self.last_state_clk = current_state_clk + + def control_motor(self, action): + """ + Control the motor based on the action from the trained model. + - action: 0 for moving left, 1 for moving right. + - Set motor direction and speed accordingly. + """ + if action == 0: + # Move motor to the left (e.g., set IN1 high, IN2 low) + gpio_write(self.motor_pin_in1, HIGH) + gpio_write(self.motor_pin_in2, LOW) + elif action == 1: + # Move motor to the right (e.g., set IN1 low, IN2 high) + gpio_write(self.motor_pin_in1, LOW) + gpio_write(self.motor_pin_in2, HIGH) + + # Optionally set the motor speed if using PWM + # pwm_write(self.motor_pwm_pin, self.motor_speed) + + def reset(self): + """ + Reset the environment to its initial state. + - Reset the angle and any other state variables. + - Return the initial state. + """ + self.angle = 0 + return self.get_state() + + def get_state(self): + """ + Get the current state of the system. + - Return the state as a tuple (angle, angle_velocity). + """ + # Calculate angular velocity if necessary + angle_velocity = calculate_angle_velocity(self.angle) + + return (self.angle, angle_velocity) + + def step(self, action): + """ + Execute one time step of the environment. + - Apply the action using the motor. + - Update the angle of the pole. + - Check if the episode is done (e.g., if the pole falls too far). + - Return the new state, reward, and done flag. + """ + self.control_motor(action) + self.update_angle() + next_state = self.get_state() + + # Define reward and done conditions based on the current state + reward = calculate_reward(next_state) + done = check_done(next_state) + + return next_state, reward, done + + def close(self): + """ + Clean up the hardware interface. + - Reset GPIO states and close any open connections. + """ + # Clean up GPIO pins + gpio_cleanup() + +# Example helper functions (to be implemented according to your setup) +def gpio_read(pin): + pass + +def gpio_write(pin, value): + pass + +def pwm_write(pin, value): + pass + +def calculate_angle_velocity(angle): + pass + +def calculate_reward(state): + pass + +def check_done(state): + pass + +def gpio_cleanup(): + pass