diff --git a/robots/BOBB3E/Backing alert.wav b/robots/BOBB3E/Backing alert.wav new file mode 100644 index 0000000..5bbed13 Binary files /dev/null and b/robots/BOBB3E/Backing alert.wav differ diff --git a/robots/BOBB3E/README.md b/robots/BOBB3E/README.md new file mode 100644 index 0000000..73bd0ed --- /dev/null +++ b/robots/BOBB3E/README.md @@ -0,0 +1,23 @@ +# BOBB3E + +> Designed by Kenneth Ravnshøj Madsen +> +> This remote controlled Bobcat® can be steered to move and lift objects with the control buttons on the IR Beacon. + +The build instructions may be found at the official LEGO MINDSTROMS site [here](https://www.lego.com/cdn/cs/set/assets/blt1e45d9c2a9800e3c/BOBB3E.pdf). + +Control BOBB3E as follows: + +- Make BOBB3E lower the forks by pressing the IR Remote Control's 2 Left Buttons together; make him raise the forks by pressing the 2 Right Buttons together + +- Drive BOBB3E around according to instructions from the IR Beacon: + - 2 Top/Up Buttons together: drive forward + - 2 Bottom/Down Buttons together: drive backward + - Top-Left/Red-Up and Bottom-Right/Blue-Down together: turn left on the spot + - Top-Right/Blue-Up and Bottom-Left/Red-Down together: turn right on the spot + - Top-Left/Red-Up: turn left forward + - Top-Right/Blue-Up: turn right forward + - Bottom-Left/Red-Down: turn left backward + - Bottom-Right/Blue-Down: turn right backward + +- BOBB3E beeps his alarm whenever reversing diff --git a/robots/BOBB3E/bobb3e.py b/robots/BOBB3E/bobb3e.py new file mode 100644 index 0000000..8e35058 --- /dev/null +++ b/robots/BOBB3E/bobb3e.py @@ -0,0 +1,209 @@ +#!/usr/bin/env micropython + + +from ev3dev2.motor import \ + Motor, LargeMotor, MediumMotor, MoveTank, MoveSteering, \ + OUTPUT_A, OUTPUT_B, OUTPUT_C +from ev3dev2.sensor import INPUT_4 +from ev3dev2.sensor.lego import InfraredSensor +from ev3dev2.console import Console +from ev3dev2.sound import Sound + +from threading import Thread +from time import sleep + + +class Bobb3e: + def __init__( + self, + left_motor_port: str = OUTPUT_B, right_motor_port: str = OUTPUT_C, + lift_motor_port: str = OUTPUT_A, + ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): + self.tank_driver = \ + MoveTank( + left_motor_port=left_motor_port, + right_motor_port=right_motor_port, + motor_class=LargeMotor) + self.steer_driver = \ + MoveSteering( + left_motor_port=left_motor_port, + right_motor_port=right_motor_port, + motor_class=LargeMotor) + self.tank_driver.left_motor.polarity = \ + self.tank_driver.right_motor.polarity = \ + self.steer_driver.left_motor.polarity = \ + self.steer_driver.right_motor.polarity = Motor.POLARITY_INVERSED + + self.lift_motor = MediumMotor(address=lift_motor_port) + + self.ir_sensor = InfraredSensor(address=ir_sensor_port) + self.ir_beacon_channel = ir_beacon_channel + + self.console = Console() + self.speaker = Sound() + + self.reversing = False + + def drive_or_operate_forks_by_ir_beacon(self, driving_speed: float = 100): + """ + Read the commands from the remote control and convert them into actions + such as go forward, lift and turn. + """ + while True: + # lower the forks + if self.ir_sensor.top_left( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.bottom_left( + channel=self.ir_beacon_channel): + self.reversing = False + + self.tank_driver.off(brake=True) + + self.lift_motor.on( + speed=10, + brake=False, + block=False) + + # raise the forks + elif self.ir_sensor.top_right( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.bottom_right( + channel=self.ir_beacon_channel): + self.reversing = False + + self.tank_driver.off(brake=True) + + self.lift_motor.on( + speed=-10, + brake=False, + block=False) + + # forward + elif self.ir_sensor.top_left( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.top_right( + channel=self.ir_beacon_channel): + self.reversing = False + + self.tank_driver.on( + left_speed=driving_speed, + right_speed=driving_speed) + + self.lift_motor.off(brake=True) + + # backward + elif self.ir_sensor.bottom_left( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.bottom_right( + channel=self.ir_beacon_channel): + self.reversing = True + + self.tank_driver.on( + left_speed=-driving_speed, + right_speed=-driving_speed) + + self.lift_motor.off(brake=True) + + # turn left on the spot + elif self.ir_sensor.top_left( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.bottom_right( + channel=self.ir_beacon_channel): + self.reversing = False + + self.steer_driver.on( + steering=-100, + speed=driving_speed) + + self.lift_motor.off(brake=True) + + # turn right on the spot + elif self.ir_sensor.top_right( + channel=self.ir_beacon_channel) and \ + self.ir_sensor.bottom_left( + channel=self.ir_beacon_channel): + self.reversing = False + + self.steer_driver.on( + steering=100, + speed=driving_speed) + + self.lift_motor.off(brake=True) + + # turn left forward + elif self.ir_sensor.top_left(channel=self.ir_beacon_channel): + self.reversing = False + + self.steer_driver.on( + steering=-50, + speed=driving_speed) + + self.lift_motor.off(brake=True) + + # turn right forward + elif self.ir_sensor.top_right(channel=self.ir_beacon_channel): + self.reversing = False + + self.steer_driver.on( + steering=50, + speed=driving_speed) + + self.lift_motor.off(brake=True) + + # turn left backward + elif self.ir_sensor.bottom_left(channel=self.ir_beacon_channel): + self.reversing = True + + self.tank_driver.on( + left_speed=0, + right_speed=-driving_speed) + + self.lift_motor.off(brake=True) + + # turn right backward + elif self.ir_sensor.bottom_right(channel=self.ir_beacon_channel): + self.reversing = True + + self.tank_driver.on( + left_speed=-driving_speed, + right_speed=0) + + self.lift_motor.off(brake=True) + + # otherwise stop + else: + self.reversing = False + + self.tank_driver.off(brake=True) + + self.lift_motor.off(brake=True) + + sleep(0.01) + + def sound_alarm_whenever_reversing(self): + while True: + if self.reversing: + self.speaker.play_file( + wav_file='/home/robot/sound/Backing alert.wav', + volume=100, + play_type=Sound.PLAY_WAIT_FOR_COMPLETE) + + sleep(0.01) + + def main(self, driving_speed: float = 100): + self.console.text_at( + text='BOBB3E', + column=3, + row=2, + reset_console=False, + inverse=False, + alignment='L') + + Thread(target=self.sound_alarm_whenever_reversing).start() + + self.drive_or_operate_forks_by_ir_beacon(driving_speed=driving_speed) + + +if __name__ == '__main__': + BOBB3E = Bobb3e() + BOBB3E.main()