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..5b05e6b --- /dev/null +++ b/robots/BOBB3E/bobb3e.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 + + +from ev3dev.ev3 import ( + Motor, MediumMotor, LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, + InfraredSensor, RemoteControl, INPUT_4, + Screen, 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.left_motor = LargeMotor(address=left_motor_port) + self.right_motor = LargeMotor(address=right_motor_port) + self.left_motor.polarity = self.right_motor.polarity = \ + Motor.POLARITY_INVERSED + + self.lift_motor = MediumMotor(address=lift_motor_port) + + self.ir_sensor = InfraredSensor(address=ir_sensor_port) + self.remote_control = RemoteControl(sensor=self.ir_sensor, + channel=ir_beacon_channel) + + self.screen = Screen() + self.speaker = Sound() + + self.reversing = False + + def drive_or_operate_forks_by_ir_beacon(self, driving_speed: float = 1000): + """ + 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.remote_control.red_up and self.remote_control.red_down: + self.reversing = False + + self.left_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + self.right_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + self.lift_motor.run_forever(speed_sp=100) + + # raise the forks + elif self.remote_control.blue_up and self.remote_control.blue_down: + self.reversing = False + + self.left_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + self.right_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + self.lift_motor.run_forever(speed_sp=-100) + + # forward + elif self.remote_control.red_up and self.remote_control.blue_up: + self.reversing = False + + self.left_motor.run_forever(speed_sp=driving_speed) + self.right_motor.run_forever(speed_sp=driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # backward + elif self.remote_control.red_down and \ + self.remote_control.blue_down: + self.reversing = True + + self.left_motor.run_forever(speed_sp=-driving_speed) + self.right_motor.run_forever(speed_sp=-driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn left on the spot + elif self.remote_control.red_up and self.remote_control.blue_down: + self.reversing = False + + self.left_motor.run_forever(speed_sp=-driving_speed) + self.right_motor.run_forever(speed_sp=driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn right on the spot + elif self.remote_control.red_down and self.remote_control.blue_up: + self.reversing = False + + self.left_motor.run_forever(speed_sp=driving_speed) + self.right_motor.run_forever(speed_sp=-driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn left forward + elif self.remote_control.red_up: + self.reversing = False + + self.right_motor.run_forever(speed_sp=driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn right forward + elif self.remote_control.blue_up: + self.reversing = False + + self.left_motor.run_forever(speed_sp=driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn left backward + elif self.remote_control.red_down: + self.reversing = True + + self.right_motor.run_forever(speed_sp=-driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # turn right backward + elif self.remote_control.blue_down: + self.reversing = True + + self.left_motor.run_forever(speed_sp=-driving_speed) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + # otherwise stop + else: + self.reversing = False + + self.left_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + self.right_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + self.lift_motor.stop(stop_action=Motor.STOP_ACTION_HOLD) + + sleep(0.01) + + def sound_alarm_whenever_reversing(self): + while True: + if self.reversing: + self.speaker.play(wav_file='Backing alert.wav').wait() + + sleep(0.01) + + def main(self, driving_speed: float = 1000): + self.screen.draw.text( + xy=(3, 2), + text='BOBB3E', + fill=None, + font=None, + anchor=None, + spacing=4, + align='left', + direction=None, + features=None, + language=None, + stroke_width=0, + stroke_fill=None) + self.screen.update() + + Thread(target=self.sound_alarm_whenever_reversing, + daemon=True).start() + + self.drive_or_operate_forks_by_ir_beacon(driving_speed=driving_speed) + + +if __name__ == '__main__': + BOBB3E = Bobb3e() + BOBB3E.main(driving_speed=1000)