class Ev3rstorm(IRBeaconRemoteControlledTank): def __init__(self, left_foot_motor_port: str = OUTPUT_B, right_foot_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): super().__init__(left_motor_port=left_foot_motor_port, right_motor_port=right_foot_motor_port, ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) self.bazooka_blast_motor = MediumMotor( address=bazooka_blast_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_port) self.screen = Screen() self.speaker = Sound() def blast_bazooka_whenever_touched(self): while True: if self.touch_sensor.is_pressed: if self.color_sensor.ambient_light_intensity < 5: # 15 not dark enough self.speaker.play( wav_file='/home/robot/sound/Up.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=-3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) else: self.speaker.play( wav_file='/home/robot/sound/Down.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) while self.touch_sensor.is_pressed: pass def main( self, driving_speed: float = 1000 # degrees per second ): self.screen.image.paste(im=Image.open('/home/robot/image/Target.bmp')) self.screen.update() Thread(target=self.blast_bazooka_whenever_touched, daemon=True).start() self.keep_driving_by_ir_beacon(speed=driving_speed)
class Ev3rstorm(RemoteControlledTank): def __init__( self, left_foot_motor_port: str = OUTPUT_B, right_foot_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3): super().__init__( left_motor=left_foot_motor_port, right_motor=right_foot_motor_port, polarity=Motor.POLARITY_NORMAL) self.bazooka_blast_motor = MediumMotor(address=bazooka_blast_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_port) self.screen = Screen() self.speaker = Sound() def blast_bazooka_whenever_touched(self): while True: if self.touch_sensor.is_pressed: if self.color_sensor.ambient_light_intensity < 5: # 15 not dark enough self.speaker.play(wav_file='/home/robot/sound/Up.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=-3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) else: self.speaker.play(wav_file='/home/robot/sound/Down.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) while self.touch_sensor.is_pressed: pass def main(self): self.screen.image.paste(im=Image.open('/home/robot/image/Target.bmp')) self.screen.update() Process(target=self.blast_bazooka_whenever_touched, daemon=True).start() super().main() # RemoteControlledTank.main()
class Ev3rstorm: def __init__(self, left_foot_track_motor_port: str = OUTPUT_B, right_foot_track_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, driving_ir_beacon_channel: int = 1, shooting_ir_beacon_channel: int = 2): self.left_foot_track_motor = LargeMotor( address=left_foot_track_motor_port) self.right_foot_track_motor = LargeMotor( address=right_foot_track_motor_port) self.bazooka_blast_motor = MediumMotor( address=bazooka_blast_motor_port) self.ir_sensor = InfraredSensor(address=ir_sensor_port) self.driving_remote_control = RemoteControl( sensor=self.ir_sensor, channel=driving_ir_beacon_channel) self.shooting_remote_control = RemoteControl( sensor=self.ir_sensor, channel=shooting_ir_beacon_channel) self.touch_sensor = TouchSensor(address=INPUT_1) self.color_sensor = ColorSensor(address=INPUT_3) self.leds = Leds() self.screen = Screen() assert self.left_foot_track_motor.connected assert self.right_foot_track_motor.connected assert self.bazooka_blast_motor.connected assert self.ir_sensor.connected assert self.touch_sensor.connected assert self.color_sensor.connected # reset the motors for motor in (self.left_foot_track_motor, self.right_foot_track_motor, self.bazooka_blast_motor): motor.reset() motor.position = 0 motor.stop_action = Motor.STOP_ACTION_BRAKE self.draw_face() def draw_face(self): w, h = self.screen.shape y = h // 2 eye_xrad = 20 eye_yrad = 30 pup_xrad = 10 pup_yrad = 10 def draw_eye(x): self.screen.draw.ellipse( (x - eye_xrad, y - eye_yrad, x + eye_xrad, y + eye_yrad)) self.screen.draw.ellipse( (x - pup_xrad, y - pup_yrad, x + pup_xrad, y + pup_yrad), fill='black') draw_eye(w // 3) draw_eye(2 * w // 3) self.screen.update() def shoot(self, direction='up'): """ Shot a ball in the specified direction (valid choices are 'up' and 'down') """ self.bazooka_blast_motor.run_to_rel_pos( speed_sp=900, # degrees per second position_sp=-3 * 360 if direction == 'up' else 3 * 360, # degrees stop_action=Motor.STOP_ACTION_BRAKE) self.bazooka_blast_motor.wait_while(Motor.STATE_RUNNING) def rc_loop( self, driving_speed: float = 1000 # degrees per second ): """ Enter the remote control loop. RC buttons on channel 1 control the robot movement, channel 2 is for shooting things. The loop ends when the touch sensor is pressed. """ def roll(motor: Motor, led_group: str, speed: float): """ Generate remote control event handler. It rolls given motor into given direction (1 for forward, -1 for backward). When motor rolls forward, the given led group flashes green, when backward -- red. When motor stops, the leds are turned off. The on_press function has signature required by RemoteControl class. It takes boolean state parameter; True when button is pressed, False otherwise. """ def on_press(state: int): if state: # roll when button is pressed motor.run_forever(speed_sp=speed) self.leds.set_color( group=led_group, color=Leds.GREEN if speed > 0 else Leds.RED, pct=1) else: # stop otherwise motor.stop(stop_action=Motor.STOP_ACTION_COAST) self.leds.set_color(group=led_group, color=Leds.BLACK, pct=1) return on_press self.driving_remote_control.on_red_up = \ roll(motor=self.right_foot_track_motor, led_group=Leds.RIGHT, speed=driving_speed) self.driving_remote_control.on_red_down = \ roll(motor=self.right_foot_track_motor, led_group=Leds.RIGHT, speed=-driving_speed) self.driving_remote_control.on_blue_up = \ roll(motor=self.left_foot_track_motor, led_group=Leds.LEFT, speed=driving_speed) self.driving_remote_control.on_blue_down = \ roll(motor=self.left_foot_track_motor, led_group=Leds.LEFT, speed=-driving_speed) def shoot(direction: str): def on_press(state: int): if state: self.shoot(direction) return on_press self.shooting_remote_control.on_red_up = shoot('up') self.shooting_remote_control.on_blue_up = shoot('up') self.shooting_remote_control.on_red_down = shoot('down') self.shooting_remote_control.on_blue_down = shoot('down') # now that the event handlers are assigned, # let's enter the processing loop: while not self.touch_sensor.is_pressed: self.driving_remote_control.process() self.shooting_remote_control.process()
LEDS.set_color(group=Leds.LEFT, color=Leds.ORANGE, pct=1) LEDS.set_color(group=Leds.RIGHT, color=Leds.ORANGE, pct=1) if REMOTE_CONTROL.beacon: heading_difference = BEACON_SEEKER.heading - (-3) proximity_difference = BEACON_SEEKER.distance - 70 if (heading_difference == 0) and (proximity_difference == 0): LEFT_FOOT_MOTOR.stop(stop_action=Motor.STOP_ACTION_HOLD) RIGHT_FOOT_MOTOR.stop(stop_action=Motor.STOP_ACTION_HOLD) LEDS.set_color(group=Leds.LEFT, color=Leds.RED, pct=1) LEDS.set_color(group=Leds.RIGHT, color=Leds.RED, pct=1) BAZOOKA_BLAST_MOTOR.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) BAZOOKA_BLAST_MOTOR.wait_while(Motor.STATE_RUNNING) SPEAKER.play(wav_file='/home/robot/sound/Laughing 2.wav').wait() else: # TODO ... else: LEFT_FOOT_MOTOR.stop(stop_action=Motor.STOP_ACTION_HOLD) RIGHT_FOOT_MOTOR.stop(stop_action=Motor.STOP_ACTION_HOLD)
SCREEN.image.paste(im=Image.open('/home/robot/image/Pinch left.bmp')) SCREEN.update() LEFT_MOTOR.run_to_rel_pos( position_sp=2 * 360, # degrees speed_sp=750, # degrees per second stop_action=Motor.STOP_ACTION_BRAKE) RIGHT_MOTOR.run_to_rel_pos( position_sp=2 * 360, # degrees speed_sp=750, # degrees per second stop_action=Motor.STOP_ACTION_BRAKE) LEFT_MOTOR.wait_while(Motor.STATE_RUNNING) RIGHT_MOTOR.wait_while(Motor.STATE_RUNNING) MEDIUM_MOTOR.run_to_rel_pos( position_sp=3 * 360, # degrees speed_sp=750, # degrees per second stop_action=Motor.STOP_ACTION_BRAKE) MEDIUM_MOTOR.wait_while(Motor.STATE_RUNNING) LEFT_MOTOR.run_to_rel_pos( position_sp=-2 * 360, # degrees speed_sp=750, # degrees per second stop_action=Motor.STOP_ACTION_BRAKE) RIGHT_MOTOR.run_to_rel_pos( position_sp=-2 * 360, # degrees speed_sp=750, # degrees per second stop_action=Motor.STOP_ACTION_BRAKE) LEFT_MOTOR.wait_while(Motor.STATE_RUNNING) RIGHT_MOTOR.wait_while(Motor.STATE_RUNNING) SPEAKER.play(wav_file='/home/robot/sound/Fanfare.wav').wait()
class Ev3rstorm: def __init__(self, left_foot_motor_port: str = OUTPUT_B, right_foot_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): self.left_foot_motor = LargeMotor(address=left_foot_motor_port) self.right_foot_motor = LargeMotor(address=right_foot_motor_port) self.bazooka_blast_motor = MediumMotor( address=bazooka_blast_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_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() def drive_once_by_ir_beacon( self, speed: float = 1000 # degrees per second ): # forward if self.remote_control.red_up and self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) self.right_foot_motor.run_forever(speed_sp=speed) # backward elif self.remote_control.red_down and self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) self.right_foot_motor.run_forever(speed_sp=-speed) # turn left on the spot elif self.remote_control.red_up and self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) self.right_foot_motor.run_forever(speed_sp=speed) # turn right on the spot elif self.remote_control.red_down and self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) self.right_foot_motor.run_forever(speed_sp=-speed) # turn left forward elif self.remote_control.red_up: self.right_foot_motor.run_forever(speed_sp=speed) # turn right forward elif self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) # turn left backward elif self.remote_control.red_down: self.right_foot_motor.run_forever(speed_sp=-speed) # turn right backward elif self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) # otherwise stop else: self.left_foot_motor.stop(stop_action=Motor.STOP_ACTION_COAST) self.right_foot_motor.stop(stop_action=Motor.STOP_ACTION_COAST) def blast_bazooka_if_touched(self): if self.touch_sensor.is_pressed: if self.color_sensor.ambient_light_intensity < 5: # 15 not dark enough self.speaker.play(wav_file='/home/robot/sound/Up.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=-3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) else: self.speaker.play(wav_file='/home/robot/sound/Down.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) while self.touch_sensor.is_pressed: pass def main( self, driving_speed: float = 1000 # degrees per second ): self.screen.image.paste(im=Image.open('/home/robot/image/Target.bmp')) self.screen.update() while True: self.drive_once_by_ir_beacon(speed=driving_speed) self.blast_bazooka_if_touched()
class Dinor3x(IRBeaconRemoteControlledTank): """ Challenges: - Can you make DINOR3X remote controlled with the IR-Beacon? - Can you attach a colorsensor to DINOR3X, and make it behave differently depending on which color is in front of the sensor (red = walk fast, white = walk slow, etc.)? """ # https://sites.google.com/site/ev3python/learn_ev3_python/using-motors MEDIUM_MOTOR_POWER_FACTOR = 1.4 def __init__(self, left_motor_port: str = OUTPUT_B, right_motor_port: str = OUTPUT_C, jaw_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): super().__init__(left_motor_port=left_motor_port, right_motor_port=right_motor_port, ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) self.jaw_motor = MediumMotor(address=jaw_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.ir_sensor = InfraredSensor(address=ir_sensor_port) self.beacon = RemoteControl(sensor=self.ir_sensor, channel=ir_beacon_channel) self.button = Button() self.speaker = Sound() def calibrate_legs(self): self.left_motor.run_forever(speed_sp=100) self.right_motor.run_forever(speed_sp=200) while self.touch_sensor.is_pressed: pass self.left_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.run_forever(speed_sp=400) while not self.touch_sensor.is_pressed: pass self.left_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.run_to_rel_pos(position_sp=-0.2 * 360, speed_sp=500, stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.wait_while(Motor.STATE_RUNNING) self.right_motor.run_forever(speed_sp=400) while not self.touch_sensor.is_pressed: pass self.right_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.run_to_rel_pos(position_sp=-0.2 * 360, speed_sp=500, stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.wait_while(Motor.STATE_RUNNING) self.left_motor.reset() self.right_motor.reset() def close_mouth(self): self.jaw_motor.run_forever(speed_sp=self.MEDIUM_MOTOR_POWER_FACTOR * 200) sleep(1) self.jaw_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) def roar(self): self.speaker.play(wav_file='/home/robot/sound/T-rex roar.wav') self.jaw_motor.run_to_rel_pos(position_sp=-60, speed_sp=self.MEDIUM_MOTOR_POWER_FACTOR * 400, stop_action=Motor.STOP_ACTION_BRAKE) self.jaw_motor.wait_while(Motor.STATE_RUNNING) # FIXME: jaw keeps opening wider and wider and doesn't close for i in range(12): self.jaw_motor.run_timed(speed_sp=-self.MEDIUM_MOTOR_POWER_FACTOR * 400, time_sp=0.05 * 1000, stop_action=Motor.STOP_ACTION_BRAKE) self.jaw_motor.wait_while(Motor.STATE_RUNNING) self.jaw_motor.run_timed(speed_sp=self.MEDIUM_MOTOR_POWER_FACTOR * 400, time_sp=0.05 * 1000, stop_action=Motor.STOP_ACTION_BRAKE) self.jaw_motor.wait_while(Motor.STATE_RUNNING) self.jaw_motor.run_forever(speed_sp=self.MEDIUM_MOTOR_POWER_FACTOR * 200) sleep(0.5) def walk_until_blocked(self): self.left_motor.run_forever(speed_sp=-400) self.right_motor.run_forever(speed_sp=-400) while self.ir_sensor.proximity >= 25: pass self.left_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) def run_away(self): self.left_motor.run_to_rel_pos(speed_sp=750, position_sp=3 * 360, stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.run_to_rel_pos(speed_sp=750, position_sp=3 * 360, stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.wait_while(Motor.STATE_RUNNING) self.right_motor.wait_while(Motor.STATE_RUNNING) def jump(self): """ Dinor3x Mission 02 Challenge: make it jump """ ... # TRANSLATED FROM EV3-G MY BLOCKS # ------------------------------- def leg_adjust(self, cyclic_degrees: float, speed: float = 1000, leg_offset_percent: float = 0, mirrored_adjust: bool = False, brake: bool = True): ... def leg_to_pos(self, speed: float = 1000, left_position: float = 0, right_position: float = 0): self.left_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.stop(stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.run_to_rel_pos( speed_sp=speed, position_sp=left_position - cyclic_position_offset( rotation_sensor=self.left_motor.position, cyclic_degrees=360), stop_action=Motor.STOP_ACTION_BRAKE) self.left_motor.wait_while(Motor.STATE_RUNNING) self.right_motor.run_to_rel_pos( speed_sp=speed, position_sp=right_position - cyclic_position_offset( rotation_sensor=self.right_motor.position, cyclic_degrees=360), stop_action=Motor.STOP_ACTION_BRAKE) self.right_motor.wait_while(Motor.STATE_RUNNING) def turn(self, speed: float = 1000, n_steps: int = 1): ... def walk(self, speed: float = 1000): ... def walk_steps(self, speed: float = 1000, n_steps: int = 1): ...
class Ev3rstorm(RemoteControlledTank): def __init__( self, left_foot_motor_port: str = OUTPUT_B, right_foot_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): super().__init__( left_motor=left_foot_motor_port, right_motor=right_foot_motor_port, polarity=Motor.POLARITY_NORMAL) self.bazooka_blast_motor = MediumMotor(address=bazooka_blast_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_port) self.ir_sensor = InfraredSensor(address=ir_sensor_port) self.leds = Leds() self.screen = Screen() self.speaker = Sound() def keep_detecting_objects_by_ir_sensor(self): while True: if self.ir_sensor.proximity < 25: self.leds.set_color( group=Leds.LEFT, color=Leds.RED, pct=1) self.leds.set_color( group=Leds.RIGHT, color=Leds.RED, pct=1) self.speaker.play(wav_file='/home/robot/sound/Object.wav').wait() self.speaker.play(wav_file='/home/robot/sound/Detected.wav').wait() self.speaker.play(wav_file='/home/robot/sound/Error alarm.wav').wait() else: self.leds.all_off() def blast_bazooka_whenever_touched(self): while True: if self.touch_sensor.is_pressed: if self.color_sensor.ambient_light_intensity < 5: # 15 not dark enough self.speaker.play(wav_file='/home/robot/sound/Up.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=-3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) else: self.speaker.play(wav_file='/home/robot/sound/Down.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) while self.touch_sensor.is_pressed: pass def main(self): self.screen.image.paste(im=Image.open('/home/robot/image/Target.bmp')) self.screen.update() # DON'T use IR Sensor in 2 different modes in the same program / loop # - https://github.com/pybricks/support/issues/62 # - https://github.com/ev3dev/ev3dev/issues/1401 # Thread(target=self.keep_detecting_objects_by_ir_sensor, # daemon=True).start() Thread(target=self.blast_bazooka_whenever_touched, daemon=True).start() super().main() # RemoteControlledTank.main()
class Catapult(IRBeaconRemoteControlledTank): def __init__(self, left_motor_port: str = OUTPUT_B, right_motor_port: str = OUTPUT_C, catapult_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): super().__init__(left_motor_port=left_motor_port, right_motor_port=right_motor_port, ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) self.catapult_motor = MediumMotor(address=catapult_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_port) self.ir_sensor = InfraredSensor(address=ir_sensor_port) self.beacon = RemoteControl(sensor=self.ir_sensor, channel=ir_beacon_channel) self.speaker = Sound() def scan_colors(self): if self.color_sensor.color == ColorSensor.COLOR_YELLOW: pass elif self.color_sensor.color == ColorSensor.COLOR_WHITE: self.speaker.play(wav_file='/home/robot/sound/Good.wav').wait() def make_noise_when_touched(self): if self.touch_sensor.is_pressed: self.speaker.play(wav_file='/home/robot/sound/Ouch.wav').wait() def throw_by_ir_beacon(self): if self.beacon.beacon: self.catapult_motor.run_to_rel_pos( speed_sp=1000, position_sp=-150, stop_action=Motor.STOP_ACTION_HOLD) self.catapult_motor.wait_while(Motor.STATE_RUNNING) self.catapult_motor.run_to_rel_pos( speed_sp=1000, position_sp=150, stop_action=Motor.STOP_ACTION_HOLD) self.catapult_motor.wait_while(Motor.STATE_RUNNING) while self.beacon.beacon: pass def main(self): self.speaker.play(wav_file='/home/robot/sound/Yes.wav').wait() while True: self.drive_once_by_ir_beacon(speed=1000) self.make_noise_when_touched() self.throw_by_ir_beacon() self.scan_colors()
class Ev3rstorm: def __init__(self, left_foot_motor_port: str = OUTPUT_B, right_foot_motor_port: str = OUTPUT_C, bazooka_blast_motor_port: str = OUTPUT_A, touch_sensor_port: str = INPUT_1, color_sensor_port: str = INPUT_3, ir_sensor_port: str = INPUT_4, ir_beacon_channel: int = 1): self.left_foot_motor = LargeMotor(address=left_foot_motor_port) self.right_foot_motor = LargeMotor(address=right_foot_motor_port) self.bazooka_blast_motor = MediumMotor( address=bazooka_blast_motor_port) self.touch_sensor = TouchSensor(address=touch_sensor_port) self.color_sensor = ColorSensor(address=color_sensor_port) self.ir_sensor = InfraredSensor(address=ir_sensor_port) self.remote_control = RemoteControl(sensor=self.ir_sensor, channel=ir_beacon_channel) self.leds = Leds() self.screen = Screen() self.speaker = Sound() def drive_once_by_ir_beacon( self, speed: float = 1000 # degrees per second ): # forward if self.remote_control.red_up and self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) self.right_foot_motor.run_forever(speed_sp=speed) # backward elif self.remote_control.red_down and self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) self.right_foot_motor.run_forever(speed_sp=-speed) # turn left on the spot elif self.remote_control.red_up and self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) self.right_foot_motor.run_forever(speed_sp=speed) # turn right on the spot elif self.remote_control.red_down and self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) self.right_foot_motor.run_forever(speed_sp=-speed) # turn left forward elif self.remote_control.red_up: self.right_foot_motor.run_forever(speed_sp=speed) # turn right forward elif self.remote_control.blue_up: self.left_foot_motor.run_forever(speed_sp=speed) # turn left backward elif self.remote_control.red_down: self.right_foot_motor.run_forever(speed_sp=-speed) # turn right backward elif self.remote_control.blue_down: self.left_foot_motor.run_forever(speed_sp=-speed) # otherwise stop else: self.left_foot_motor.stop(stop_action=Motor.STOP_ACTION_COAST) self.right_foot_motor.stop(stop_action=Motor.STOP_ACTION_COAST) def dance_if_ir_beacon_pressed(self): while self.remote_control.beacon: self.left_foot_motor.run_timed(speed_sp=randint(-1000, 1000), time_sp=1000, stop_action=Motor.STOP_ACTION_COAST) self.right_foot_motor.run_timed( speed_sp=randint(-1000, 1000), time_sp=1000, stop_action=Motor.STOP_ACTION_COAST) self.left_foot_motor.wait_while(Motor.STATE_RUNNING) self.right_foot_motor.wait_while(Motor.STATE_RUNNING) def detect_object_by_ir_sensor(self): if self.ir_sensor.proximity < 25: self.leds.set_color(group=Leds.LEFT, color=Leds.RED, pct=1) self.leds.set_color(group=Leds.RIGHT, color=Leds.RED, pct=1) self.speaker.play(wav_file='/home/robot/sound/Object.wav').wait() self.speaker.play(wav_file='/home/robot/sound/Detected.wav').wait() self.speaker.play( wav_file='/home/robot/sound/Error alarm.wav').wait() else: self.leds.all_off() def blast_bazooka_if_touched(self): if self.touch_sensor.is_pressed: if self.color_sensor.ambient_light_intensity < 5: # 15 not dark enough self.speaker.play(wav_file='/home/robot/sound/Up.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=-3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) else: self.speaker.play(wav_file='/home/robot/sound/Down.wav').wait() self.bazooka_blast_motor.run_to_rel_pos( speed_sp=1000, # degrees per second position_sp=3 * 360, # degrees stop_action=Motor.STOP_ACTION_HOLD) while self.touch_sensor.is_pressed: pass def main( self, driving_speed: float = 1000 # degrees per second ): self.screen.image.paste(im=Image.open('/home/robot/image/Target.bmp')) self.screen.update() while True: self.drive_once_by_ir_beacon(speed=driving_speed) self.dance_if_ir_beacon_pressed() # DON'T use IR Sensor in 2 different modes in the same program / loop # - https://github.com/pybricks/support/issues/62 # - https://github.com/ev3dev/ev3dev/issues/1401 # self.detect_object_by_ir_sensor() self.blast_bazooka_if_touched()
from time import sleep from ev3dev.ev3 import MediumMotor, UltrasonicSensor us = UltrasonicSensor() SM = MediumMotor("outC") def sonicValue(tolerance=10): cache = [1, 100] while abs(cache[0] - cache[1]) > tolerance and not (cache[0] > 21.5 and cache[1] > 21.5): cache[0] = us.value() / 10 sleep(0.025) cache[1] = us.value() / 10 sleep(0.025) return sum(cache) / len(cache) data = [0, 0, 0] while True: data[1] = sonicValue() SM.run_to_rel_pos(position_sp=90, speed_sp=1550, stop_action="hold") sleep(0.16) data[0] = sonicValue() SM.run_to_rel_pos(position_sp=-180, speed_sp=1550, stop_action="hold") sleep(0.35) data[2] = sonicValue() SM.run_to_rel_pos(position_sp=90, speed_sp=1550, stop_action="hold") sleep(0.2)
class VerticalMovementManager: """ Initializes the manager. whereMotor - interface on which vertical motor is attached """ def __init__(self, whereMotor=OUTPUT_A): # Initialize motor self._motor = MediumMotor(whereMotor) if not self._motor.connected: raise ValueError("Medium motor at " + whereMotor + " not connected!") self._motor.stop_action = MediumMotor.STOP_ACTION_HOLD # Default speed is 0, setting this is necessary self._motor.speed_sp = 500 # Position of the lift in percentage units, preserved across runs self._pkl_pos = LiftPos.BOTTOM # TODO if we need sensors for other things, initialize this manager # outside of VerticalMovementManager and only pass a reference self._sensors = ArduinoSensorsManager() """ Sets the stored position of the lift. Useful when it was moved manually or fell. """ def set_position(self, pos): self._pkl_pos = pos """ Moves the lift to the specified percentage position. Doesn't use any sensors besides the motor tacho count. pos - where to move """ def _move_to_raw(self, pos): if self._pkl_pos != pos: curr_pos_m = percent_to_motor( self._pkl_pos) # Current position [motor] pos_m = percent_to_motor(pos) # Desired position [motor] self._motor.run_to_rel_pos(position_sp=pos_m - curr_pos_m) self._motor.wait_until_not_moving() self._pkl_pos = pos class _MoveWhileResult(Enum): STALLED = 1, # Engine was stalled OVER_RANGE = 2, # Stopped at percentage range boundary OVER_LIM = 3, # Stopped at given limit COND = 4, # Stopped due to condition False """ Moves with the specified slowdown for as long as the given condition evalutes to True. An optional maximum distance in motor units can be specified. Makes sure not to go outside of the valid position range. Returns the distance travelled in motor units. cond - () -> Boolean function. evaluated as frequently as possible. movement stops when False mult - how many times to slow down. larger values allow for more precision and an earlier stop [lim] - maximum distance to travel in motor units """ def _move_while(self, cond, mult=4, lim=None): print("_move_while(cond={},mult={},lim={})".format(cond, mult, lim)) # First position within valid range if self._pkl_pos < 0: self._move_to_raw(0) elif self._pkl_pos > 100: self._move_to_raw(100) init_pos = self._motor.position sign = mult // abs(mult) # Set motor parameters self._motor.speed_sp //= mult self._motor.polarity = 'normal' if mult > 0 else 'inversed' self._motor.run_forever() ret = None while self._motor.is_running and cond(): if self._motor.is_stalled: ret = self._MoveWhileResult.STALLED break else: motor_pos = self._motor.position * sign diff = motor_pos - init_pos if lim != None and diff >= lim: ret = self._MoveWhileResult.OVER_LIM break new_pos = self._pkl_pos + motor_to_percent(diff) if new_pos <= -2 or new_pos >= 102: ret = self._MoveWhileResult.OVER_RANGE break if ret == None: ret = self._MoveWhileResult.COND # Reset motor parameters self._motor.stop() self._motor.polarity = 'normal' self._motor.speed_sp *= mult # Update position diff = self._motor.position - init_pos self._pkl_pos += motor_to_percent(diff) return ret """ Tries to position the lift in the middle of the switch. reed - Reed switch number pos - an approximate percentage position of the switch """ def _move_to_switch(self, reed, pos): print("_move_to_switch(reed={},pos={})".format(reed, pos)) SPREAD = 7 # Minimum distance to the sensor to begin sensing # Distance and direction to the sensor diff = pos - self._pkl_pos sign = int(diff / abs(diff)) assert (abs(sign) == 1) see_mag = lambda: self._sensors.read_reed(reed) if abs(diff) >= SPREAD: if sign > 0: print("Switch above lift") else: print("Switch below lift") # Move up to sensor at full speed, pray it doesn't miss mvd = self._move_while(lambda: not see_mag(), sign) if mvd != self._MoveWhileResult.COND and mvd != self._MoveWhileResult.OVER_RANGE: raise ValueError( "ERROR: Sensor not within reach. Move result: " + str(mvd)) # Scale the peak to get to the center, use reduced speed for accuracy mvd = self._move_while(see_mag, 5 * sign, 1000) else: print("WARNING: Lift close to desired position, not moving.") return # First find one of the peaks mult = 4 * sign if not see_mag(): print("Looking for peak 1") diff = 500 mvd = self._move_while(lambda: not see_mag(), mult, diff) while mvd != self._MoveWhileResult.COND: print(mvd) print("Moved far, reverting search direction") diff *= 2 mult *= -1 mvd = self._move_while(lambda: not see_mag(), mult, diff) sign = int(mult / abs(mult)) peak1 = [0, 0] peak2 = [0, 0] # We're on a peak, find its limits by going up and down #print("Scanning peak 1") self._move_while(see_mag, mult) peak1[(sign + 1) // 2] = self._motor.position #print("Scanning peak 1 in 2nd direction") # Move a tiny bit down to be within peak again mvd = self._move_while(lambda: not see_mag(), -mult, 500) if mvd != self._MoveWhileResult.COND: raise ValueError("ERROR: peak 1 not within reach") self._move_while(see_mag, -mult) peak1[(-sign + 1) // 2] = self._motor.position print(peak1) return #print("Looking for peak 2") mvd = self._move_while(lambda: not see_mag(), -4, 250) if mvd == self._MoveWhileResult.OVER_LIM or mvd == self._MoveWhileResult.OVER_RANGE: #print("Moved far down from peak 1, so peak 2 is above. Moving to center") self._move_to_raw(self._pkl_pos + motor_to_percent(peak1[1] - self._motor.position)) self._move_to_raw(self._pkl_pos + 1) else: #print("Moved just a bit from peak 1, so peak 2 is below. Moving to center") top = self._motor.position self._move_to_raw(self._pkl_pos + motor_to_percent(peak1[0] - top) / 2) """ Moves the lift to the specified percentage position, using all available information. pos - where to move """ def move_to(self, pos): if not self._pkl_pos == pos: reed = get_reed_id(pos) if reed is not None: # If there is a sensor at that height, position the lift # accurately until it's at the sensor self._move_to_switch(reed, pos) else: # Otherwise move to the position using just the tacho count self._move_to_raw(pos)