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 (ev3dev1) #62

Open
wants to merge 11 commits into
base: jessie
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.
74 changes: 74 additions & 0 deletions robots/ROBODOZ3R/rc_tank_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3


from ev3dev.ev3 import \
Motor, LargeMotor, OUTPUT_B, OUTPUT_C, \
InfraredSensor, RemoteControl, INPUT_4


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,
polarity: str = Motor.POLARITY_NORMAL,
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 = polarity

self.ir_sensor = InfraredSensor(address=ir_sensor_port)
self.tank_drive_remote_control = \
RemoteControl(
sensor=self.ir_sensor,
channel=ir_beacon_channel)

def drive_by_ir_beacon(self, speed: float = 1000):
# forward
if self.tank_drive_remote_control.red_up and \
self.tank_drive_remote_control.blue_up:
self.left_motor.run_forever(speed_sp=speed)
self.right_motor.run_forever(speed_sp=speed)

# backward
elif self.tank_drive_remote_control.red_down and \
self.tank_drive_remote_control.blue_down:
self.left_motor.run_forever(speed_sp=-speed)
self.right_motor.run_forever(speed_sp=-speed)

# turn left on the spot
elif self.tank_drive_remote_control.red_up and \
self.tank_drive_remote_control.blue_down:
self.left_motor.run_forever(speed_sp=-speed)
self.right_motor.run_forever(speed_sp=speed)

# turn right on the spot
elif self.tank_drive_remote_control.red_down and \
self.tank_drive_remote_control.blue_up:
self.left_motor.run_forever(speed_sp=speed)
self.right_motor.run_forever(speed_sp=-speed)

# turn left forward
elif self.tank_drive_remote_control.red_up:
self.right_motor.run_forever(speed_sp=speed)

# turn right forward
elif self.tank_drive_remote_control.blue_up:
self.left_motor.run_forever(speed_sp=speed)

# turn left backward
elif self.tank_drive_remote_control.red_down:
self.right_motor.run_forever(speed_sp=-speed)

# turn right backward
elif self.tank_drive_remote_control.blue_down:
self.left_motor.run_forever(speed_sp=-speed)

# otherwise stop
else:
self.left_motor.stop(stop_action=Motor.STOP_ACTION_COAST)
self.right_motor.stop(stop_action=Motor.STOP_ACTION_COAST)
145 changes: 145 additions & 0 deletions robots/ROBODOZ3R/robodoz3r.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/usr/bin/env python3


from ev3dev.ev3 import (
Motor, MediumMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C,
TouchSensor, RemoteControl, INPUT_1, INPUT_4,
Screen, 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,
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_remote_control = \
RemoteControl(
sensor=self.ir_sensor,
channel=shovel_control_ir_beacon_channel)

self.screen = Screen()
self.speaker = Sound()

def raise_or_lower_shovel_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 pressing either Up button,
or lower the shovel by pressing either Down button.
"""
# raise the shovel
if self.shovel_control_remote_control.red_up or \
self.shovel_control_remote_control.blue_up:
self.shovel_motor.run_forever(speed_sp=100)

# lower the shovel
elif self.shovel_control_remote_control.red_down or \
self.shovel_control_remote_control.blue_down:
self.shovel_motor.run_forever(speed_sp=-100)

else:
self.shovel_motor.stop(stop_action=Motor.STOP_ACTION_HOLD)

def main(self, driving_speed: float = 1000):
"""
This is the main control program for the RoboDoz3r
"""
self.screen.draw.text(
xy=(2, 2),
text='ROBODOZ3R',
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()

self.speaker.play(wav_file='media/Motor start.wav').wait()

# Engine Idle:
# Let the engine sound idle for 2 seconds
motor_idle_start_time = time()
while time() - motor_idle_start_time <= 2:
self.speaker.play(
wav_file='media/Motor idle.wav').wait()

while True:
# Driving Mode:
# Manual mode where the movement of the RoboDoz3r is controlled
# by the IR remote
while not self.touch_sensor.is_pressed:
self.raise_or_lower_shovel_by_ir_beacon()
self.drive_by_ir_beacon(speed=driving_speed)
sleep(0.01)

self.speaker.play(wav_file='media/Airbrake.wav').wait()

# Auto Mode:
# In autonomous mode the RoboDoz3r uses the IR sensor
# in proximity mode to detect nearby obstacles in its path
while not self.touch_sensor.is_pressed:
if self.ir_sensor.proximity < 50:
self.left_motor.stop(stop_action=Motor.STOP_ACTION_HOLD)
self.right_motor.stop(stop_action=Motor.STOP_ACTION_HOLD)

sleep(1)

self.left_motor.run_timed(
speed_sp=-300,
time_sp=1000,
stop_action=Motor.STOP_ACTION_HOLD)
self.right_motor.run_timed(
speed_sp=-300,
time_sp=1000,
stop_action=Motor.STOP_ACTION_HOLD)
self.left_motor.wait_while(Motor.STATE_RUNNING)
self.right_motor.wait_while(Motor.STATE_RUNNING)

self.left_motor.run_timed(
speed_sp=500,
time_sp=1000,
stop_action=Motor.STOP_ACTION_HOLD)
self.right_motor.run_timed(
speed_sp=-500,
time_sp=1000,
stop_action=Motor.STOP_ACTION_HOLD)
self.left_motor.wait_while(Motor.STATE_RUNNING)
self.right_motor.wait_while(Motor.STATE_RUNNING)

else:
self.left_motor.run_forever(speed_sp=500)
self.right_motor.run_forever(speed_sp=500)

sleep(0.01)

self.speaker.play(wav_file='media/Airbrake.wav').wait()


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