Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add RoboDoz3r program #61

Open
wants to merge 14 commits into
base: stretch
Choose a base branch
from
27 changes: 27 additions & 0 deletions robots/ROBODOZ3R/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ROBODOZ3R

> Designed by Mark Crosbie.
>
> This robot bulldozer can be controlled using the IR Beacon or it can drive on it’s own, avoiding obstacles while clearing and pushing things with its bulldozer bucket.

The build instructions may be found at the official LEGO MINDSTROMS site [here](https://www.lego.com/cdn/cs/set/assets/bltfef825595f55768c/ROBODOZ3R.pdf)

Control ROBODOZ3R as follows:

- ROBODOZ3R starts with the User-Controlled Mode. You can switch between the User-Controlled Mode and the Autonomous Mode by pressing the Touch Sensor.

- User-Controlled Mode:

- Drive ROBODOZ3R around according to instructions from Channel 1 of the IR Remote Control:
- 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

- Use Channel 4 of the IR Remote Control to make ROBODOZ3R raise the shovel by pressing either Up button, or lower the shovel by pressing either Down button

- Autonomous Mode: ROBODOZ3R drives around on his own to clean up small things but avoids big obstacles by reversing and turning
Binary file added robots/ROBODOZ3R/media/Airbrake.wav
Binary file not shown.
Binary file added robots/ROBODOZ3R/media/Motor idle.wav
Binary file not shown.
Binary file added robots/ROBODOZ3R/media/Motor start.wav
Binary file not shown.
Binary file added robots/ROBODOZ3R/media/Motor stop.wav
Binary file not shown.
Binary file added robots/ROBODOZ3R/media/Start up.wav
Binary file not shown.
105 changes: 105 additions & 0 deletions robots/ROBODOZ3R/rc_tank_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from ev3dev2.motor import \
Motor, LargeMotor, MoveSteering, MoveTank, \
OUTPUT_B, OUTPUT_C
from ev3dev2.sensor import INPUT_4
from ev3dev2.sensor.lego import InfraredSensor


class RemoteControlledTank:
"""
This reusable mixin provides the capability of driving a robot
with a Driving Base by the IR beacon
"""
def __init__(
self,
left_motor_port: str = OUTPUT_B, right_motor_port: str = OUTPUT_C,
motor_class=LargeMotor, polarity: str = Motor.POLARITY_NORMAL,
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=motor_class)

self.steer_driver = \
MoveSteering(
left_motor_port=left_motor_port,
right_motor_port=right_motor_port,
motor_class=motor_class)

self.tank_driver.left_motor.polarity = \
self.tank_driver.right_motor.polarity = \
self.steer_driver.left_motor.polarity = \
self.steer_driver.right_motor.polarity = polarity

self.ir_sensor = InfraredSensor(address=ir_sensor_port)
self.tank_drive_ir_beacon_channel = ir_beacon_channel

def drive_by_ir_beacon(self, speed: float = 100):
# forward
if self.ir_sensor.top_left(
channel=self.tank_drive_ir_beacon_channel) and \
self.ir_sensor.top_right(
channel=self.tank_drive_ir_beacon_channel):
self.tank_driver.on(
left_speed=speed,
right_speed=speed)

# backward
elif self.ir_sensor.bottom_left(
channel=self.tank_drive_ir_beacon_channel) and \
self.ir_sensor.bottom_right(
channel=self.tank_drive_ir_beacon_channel):
self.tank_driver.on(
left_speed=-speed,
right_speed=-speed)

# turn left on the spot
elif self.ir_sensor.top_left(
channel=self.tank_drive_ir_beacon_channel) and \
self.ir_sensor.bottom_right(
channel=self.tank_drive_ir_beacon_channel):
self.steer_driver.on(
steering=-100,
speed=speed)

# turn right on the spot
elif self.ir_sensor.top_right(
channel=self.tank_drive_ir_beacon_channel) and \
self.ir_sensor.bottom_left(
channel=self.tank_drive_ir_beacon_channel):
self.steer_driver.on(
steering=100,
speed=speed)

# turn left forward
elif self.ir_sensor.top_left(
channel=self.tank_drive_ir_beacon_channel):
self.steer_driver.on(
steering=-50,
speed=speed)

# turn right forward
elif self.ir_sensor.top_right(
channel=self.tank_drive_ir_beacon_channel):
self.steer_driver.on(
steering=50,
speed=speed)

# turn left backward
elif self.ir_sensor.bottom_left(
channel=self.tank_drive_ir_beacon_channel):
self.tank_driver.on(
left_speed=0,
right_speed=-speed)

# turn right backward
elif self.ir_sensor.bottom_right(
channel=self.tank_drive_ir_beacon_channel):
self.tank_driver.on(
left_speed=-speed,
right_speed=0)

# otherwise stop
else:
self.tank_driver.off(brake=False)
139 changes: 139 additions & 0 deletions robots/ROBODOZ3R/robodoz3r.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/env micropython


from ev3dev2.motor import \
Motor, LargeMotor, MediumMotor, \
OUTPUT_A, OUTPUT_B, OUTPUT_C
from ev3dev2.sensor import INPUT_1, INPUT_4
from ev3dev2.sensor.lego import TouchSensor
from ev3dev2.console import Console
from ev3dev2.sound import Sound

from time import sleep, time

from rc_tank_util import RemoteControlledTank


class RoboDoz3r(RemoteControlledTank):
def __init__(
self,
left_motor_port: str = OUTPUT_C, right_motor_port: str = OUTPUT_B,
shovel_motor_port: str = OUTPUT_A,
touch_sensor_port: str = INPUT_1,
ir_sensor_port: str = INPUT_4,
tank_drive_ir_beacon_channel: int = 1,
shovel_control_ir_beacon_channel: int = 4):
super().__init__(
left_motor_port=left_motor_port, right_motor_port=right_motor_port,
motor_class=LargeMotor, polarity=Motor.POLARITY_INVERSED,
ir_sensor_port=ir_sensor_port,
ir_beacon_channel=tank_drive_ir_beacon_channel)

self.shovel_motor = MediumMotor(address=shovel_motor_port)

self.touch_sensor = TouchSensor(address=touch_sensor_port)

self.shovel_control_ir_beacon_channel = \
shovel_control_ir_beacon_channel

self.console = Console()
self.speaker = Sound()

def raise_or_lower_shovel_once_by_ir_beacon(self):
"""
If the channel 4 is selected on the IR remote
then you can control raising and lowering the shovel on the RoboDoz3r
- Raise the shovel by either Up button
- Raise the shovel by either Down button
"""
# raise the shovel
if self.ir_sensor.top_left(
channel=self.shovel_control_ir_beacon_channel) or \
self.ir_sensor.top_right(
channel=self.shovel_control_ir_beacon_channel):
self.shovel_motor.on(
speed=10,
brake=False,
block=False)

# lower the shovel
elif self.ir_sensor.bottom_left(
channel=self.shovel_control_ir_beacon_channel) or \
self.ir_sensor.bottom_right(
channel=self.shovel_control_ir_beacon_channel):
self.shovel_motor.on(
speed=-10,
brake=False,
block=False)

else:
self.shovel_motor.off(brake=True)

def main(self, driving_speed: float = 100):
self.console.text_at(
text='ROBODOZ3R',
column=2,
row=2,
reset_console=False,
inverse=False,
alignment='L')

self.speaker.play_file(
wav_file='media/Motor start.wav',
volume=56,
play_type=Sound.PLAY_WAIT_FOR_COMPLETE)

motor_idle_start_time = time()
while time() - motor_idle_start_time <= 2:
self.speaker.play_file(
wav_file='media/Motor idle.wav',
volume=51,
play_type=Sound.PLAY_WAIT_FOR_COMPLETE)

while True:
while self.touch_sensor.is_released:
self.raise_or_lower_shovel_once_by_ir_beacon()
self.drive_by_ir_beacon(speed=driving_speed)
sleep(0.01)

self.speaker.play_file(
wav_file='media/Airbrake.wav',
volume=100,
play_type=Sound.PLAY_WAIT_FOR_COMPLETE)

while self.touch_sensor.is_released:
if self.ir_sensor.proximity < 50:
self.tank_driver.off(brake=True)

sleep(1)

self.tank_driver.on_for_seconds(
left_speed=-30,
right_speed=-30,
seconds=1,
brake=True,
block=True)

self.tank_driver.on_for_seconds(
left_speed=50,
right_speed=-50,
seconds=1,
brake=True,
block=True)

else:
self.tank_driver.on(
left_speed=50,
right_speed=50)

sleep(0.01)

self.speaker.play_file(
wav_file='media/Airbrake.wav',
volume=100,
play_type=Sound.PLAY_WAIT_FOR_COMPLETE)


if __name__ == '__main__':
ROBODOZ3R = RoboDoz3r()
ROBODOZ3R.main()