Beispiel #1
0
    def run_for_time(self,
                     msec,
                     speed,
                     stop=MotorStop.BRAKE,
                     block=True,
                     **kwargs):
        """
        Run the motor at ``speed`` for ``msec``

        Args:
            msec (int): the number of milliseconds to run the motor
            speed (MotorSpeed): the speed of the motor
            stop (MotorStop): how to stop the motors, defaults to :class:`MotorStop.BRAKE`
            block (bool): if True this function will not return until the motors have finished moving
            **kwargs: optional kwargs that will pass all the way down to the LEGO ``hub.port.X.motor`` API call
        """

        if msec < 0:
            raise ValueError("msec was {}, must be >= 0".format(msec))
        elif msec == 0:
            return

        raw_speed = self._speed_percentage(speed)
        log_msg(
            "{}: run_for_time {}ms at speed {}, raw_speed {}, stop {}, block {}"
            .format(self, msec, speed, raw_speed, stop, block))
        self.rxed_callback = False
        self.port_motor.run_for_time(msec, raw_speed, stop=stop, **kwargs)

        if block:
            self._wait()
Beispiel #2
0
    def run_for_distance(self,
                         distance,
                         speed,
                         stop=MotorStop.BRAKE,
                         block=True,
                         **kwargs):
        """
        Drive in a straight line for ``distance``

        Args:
            distance (DistanceValue): how far the midpoint between the wheels should travel
            speed (MotorSpeed): how fast the midpoint between the wheels should travel
            stop (MotorStop): how to stop the motors, defaults to :class:`MotorStop.BRAKE`
            block (bool): if True this function will not return until the motors have finished moving
            **kwargs: optional kwargs that will pass all the way down to the LEGO ``hub.port.X.motor`` API call
        """
        distance_mm = distance_in_mm(distance)
        rotations = distance_mm / self.wheel.circumference_mm
        degrees = int(rotations * 360)
        log_msg("{}: run_for_distance distance_mm {}, rotations {}, speed {}".
                format(self, distance_mm, rotations, speed))
        MoveTank.run_for_degrees(self,
                                 degrees,
                                 speed,
                                 speed,
                                 stop=stop,
                                 block=block,
                                 **kwargs)
Beispiel #3
0
    def run_to_position(self,
                        left_position,
                        right_position,
                        speed,
                        stop=MotorStop.BRAKE,
                        block=True,
                        **kwargs):
        """
        Run both motors at ``speed`` to the desired positions

        Args:
            left_position (int): the target position for the left motor
            right_position (int): the target position for the right motor
            speed (MotorSpeed): the speed of both motors
            stop (MotorStop): how to stop the motors, defaults to :class:`MotorStop.BRAKE`
            block (bool): if True this function will not return until the motors have finished moving
            **kwargs: optional kwargs that will pass all the way down to the LEGO ``hub.port.X.motor`` API call
        """
        log_msg(
            "{}: run_to_position left_position {}, right_position {}, at speed {}"
            .format(self, left_position, right_position, speed))
        speed = self._speed_percentage(speed)
        self.rxed_callback = False
        self.pair.run_to_position(left_position,
                                  right_position,
                                  speed,
                                  stop=stop,
                                  **kwargs)

        if block:
            self._wait()
Beispiel #4
0
    def run_for_degrees(self,
                        degrees,
                        left_speed,
                        right_speed,
                        stop=MotorStop.BRAKE,
                        block=True,
                        **kwargs):
        """
        Run the motors at the specified speeds, the two motors combined will move an average of ``degrees``

        Args:
            degrees (int): the average number of degrees for the two motors to move
            left_speed (MotorSpeed): the speed of the left motor
            right_speed (MotorSpeed): the speed of the right motor
            stop (MotorStop): how to stop the motors, defaults to :class:`MotorStop.BRAKE`
            block (bool): if True this function will not return until the motors have finished moving
            **kwargs: optional kwargs that will pass all the way down to the LEGO ``hub.port.X.motor`` API call
        """
        log_msg(
            "{}: run_for_degrees {} at left_speed {}, right_speed {}".format(
                self, degrees, left_speed, right_speed))
        left_speed = self._speed_percentage(left_speed)
        right_speed = self._speed_percentage(right_speed)
        self.rxed_callback = False
        (left_speed,
         right_speed) = self._speed_with_polarity(left_speed, right_speed)
        self.pair.run_for_degrees(degrees,
                                  left_speed,
                                  right_speed,
                                  stop=stop,
                                  **kwargs)

        if block:
            self._wait()
Beispiel #5
0
    def _run_arc(self, radius_mm, distance_mm, speed, stop, block, arc_right,
                 **kwargs):
        """
        Drive in a circle with ``radius`` for ``distance``
        """

        if radius_mm < self.min_circle_radius_mm:
            raise ValueError(
                "{}: radius_mm {} is less than min_circle_radius_mm {}".format(
                    self, radius_mm, self.min_circle_radius_mm))

        speed = self._speed_percentage(speed)

        # The circle formed at the halfway point between the two wheels is the
        # circle that must have a radius of radius_mm
        circle_outer_mm = 2 * math.pi * (radius_mm +
                                         (self.wheel_distance_mm / 2))
        # circle_middle_mm = 2 * math.pi * radius_mm
        circle_inner_mm = 2 * math.pi * (radius_mm -
                                         (self.wheel_distance_mm / 2))

        if arc_right:
            # The left wheel is making the larger circle and will move at 'speed'
            # The right wheel is making a smaller circle so its speed will be a fraction of the left motor's speed
            left_speed = speed
            right_speed = float(circle_inner_mm / circle_outer_mm) * left_speed

        else:
            # The right wheel is making the larger circle and will move at 'speed'
            # The left wheel is making a smaller circle so its speed will be a fraction of the right motor's speed
            right_speed = speed
            left_speed = float(circle_inner_mm / circle_outer_mm) * right_speed

        avg_wheel_rotations = float(distance_mm / self.wheel.circumference_mm)
        avg_wheel_degrees = int(avg_wheel_rotations * 360)
        log_msg(
            "{}: arc {}, radius {}, distance {}, left-speed {}, right-speed {}, "
            .format(self, "right" if arc_right else "left", radius_mm,
                    distance_mm, left_speed, right_speed) +
            "wheel circumference_mm {}, avg_wheel_rotations {}, avg_wheel_degrees {}"
            .format(self.wheel.circumference_mm, avg_wheel_rotations,
                    avg_wheel_degrees))

        MoveTank.run_for_degrees(self,
                                 avg_wheel_degrees,
                                 left_speed,
                                 right_speed,
                                 stop=stop,
                                 block=block,
                                 **kwargs)
Beispiel #6
0
    def run_for_time(self,
                     msec,
                     left_speed,
                     right_speed,
                     stop=MotorStop.BRAKE,
                     block=True,
                     **kwargs):
        """
        Run the motors at the specified speeds for ``msec``

        Args:
            msec (int): the number of milliseconds to run the motors
            left_speed (MotorSpeed): the speed of the left motor
            right_speed (MotorSpeed): the speed of the right motor
            stop (MotorStop): how to stop the motors, defaults to :class:`MotorStop.BRAKE`
            block (bool): if True this function will not return until the motors have finished moving
            **kwargs: optional kwargs that will pass all the way down to the LEGO ``hub.port.X.motor`` API call
        """
        """
        rxed_callback = False

        def local_callback(reason):
            rxed_callback = True
            log_msg("rxed callback with reason {}".format(reason))

        if block:
            self.pair.callback(local_callback)
        else:
            self.pair.callback(None)
        """

        log_msg(
            "{}: run_for_time {}ms at left_speed {}, right_speed {}".format(
                self, msec, left_speed, right_speed))
        left_speed = self._speed_percentage(left_speed)
        right_speed = self._speed_percentage(right_speed)
        (left_speed,
         right_speed) = self._speed_with_polarity(left_speed, right_speed)
        self.rxed_callback = False
        self.pair.run_for_time(msec,
                               left_speed,
                               right_speed,
                               stop=stop,
                               **kwargs)

        if block:
            self._wait()
Beispiel #7
0
def _callback(mtr, reason):
    if reason == MotorCallbackEvent.COMPLETED:
        mtr.interrupted = False
        mtr.stalled = False
        # log_msg("{}: _callback COMPLETED".format(mtr))

    elif reason == MotorCallbackEvent.INTERRUPTED:
        mtr.interrupted = True
        mtr.stalled = False
        log_msg("{}: _callback INTERRUPTED".format(mtr))

    elif reason == MotorCallbackEvent.STALL:
        mtr.interrupted = False
        mtr.stalled = True
        log_msg("{}: _callback STALL".format(mtr))

    else:
        raise ValueError("invalid callback reason {}".format(reason))

    mtr.rxed_callback = True
Beispiel #8
0
    def wait_for_bump(self, timeout_ms=None):
        """
        Wait ``timeout_ms`` for the ``TouchSensor`` to be bumped. Return ``True`` if the
        button was bumped within ``timeout_ms``, else return ``False``. If ``timeout_ms``
        is ``None`` this will wait for forever.
        """

        if self.is_pressed():
            if self.wait_for_released(timeout_ms):
                log_msg("{} bumped".format(self))
                return True
            else:
                log_msg("{} was not bumped within {}ms".format(
                    self, timeout_ms))
                return False
        else:
            if self.wait_for_pressed(timeout_ms) and self.wait_for_released(
                    timeout_ms):
                log_msg("{} bumped".format(self))
                return True
            else:
                log_msg("{} was not bumped within {}ms".format(
                    self, timeout_ms))
                return False
Beispiel #9
0
    def wait_for_pressed(self, timeout_ms=None):
        """
        Wait ``timeout_ms`` for the button to be pressed. Return ``True`` if the
        button was pressed within ``timeout_ms``, else return ``False``. If ``timeout_ms``
        is ``None`` this will wait for forever.
        """

        if self.is_pressed():
            log_msg("{} already pressed".format(self))
            return True

        self._rxed_callback = False

        if self._wait(timeout_ms):
            log_msg("{} pressed".format(self))
            return True
        else:
            log_msg("{} was not pressed within {}ms".format(self, timeout_ms))
            return False
Beispiel #10
0
    def wait_for_released(self, timeout_ms=None):
        """
        Wait ``timeout_ms`` for the ``TouchSensor`` to be released. Return ``True`` if the
        button was released within ``timeout_ms``, else return ``False``. If ``timeout_ms``
        is ``None`` this will wait for forever.
        """

        if self.is_released():
            log_msg("{} already released".format(self))
            return True

        stopwatch = StopWatch()
        stopwatch.start()

        while not self.is_released():
            if timeout_ms is not None and stopwatch.value_ms >= timeout_ms:
                log_msg("{} was not released within {}ms".format(
                    self, timeout_ms))
                return False

            utime.sleep(0.01)

        log_msg("{} released".format(self))
        return True
# standard libraries
import utime

# third party libraries
import hub

# spikedev libraries
from spikedev.logging import log_msg
from spikedev.sensor import DistanceSensor, DistanceSensorMode

log_msg("start")
ds = DistanceSensor(hub.port.A, mode=DistanceSensorMode.DISTL)

for x in range(10):
    log_msg(ds.value())
    utime.sleep(0.1)

log_msg("finish")
Beispiel #12
0
# third party libraries
import hub

# spikedev libraries
from spikedev.logging import log_msg
from spikedev.sensor import TouchSensor, TouchSensorMode

log_msg("start")
ts = TouchSensor(hub.port.B, mode=TouchSensorMode.TOUCH)
ts.wait_for_bump(5000)
log_msg("finish")