legoEv3/ev3dev2/__pycache__/motor.cpython-35.pyc




[^4@sddlZejddfkr-edddlZddlZddlmZddlmZm    Z
mZddlm
Z
ddlmZmZmZeeZd    ZeZed
krddlmZmZmZmZnedkrddlmZmZmZmZned
krKddlmZmZmZmZnedkr|ddlmZmZmZmZnredkrddlmZmZmZmZnAedkrddlmZmZmZmZne deGdddZ!Gddde!Z"Gddde!Z#Gddde!Z$Gddde!Z%Gddde!Z&Gddde!Z'Gd d!d!eZ(e(j)d"d#Z*Gd$d%d%e(Z+Gd&d'd'e(Z,Gd(d)d)e(Z-Gd*d+d+e(Z.Gd,d-d-eZ/Gd.d/d/eZ0Gd0d1d1e1Z2Gd2d3d3e2Z3Gd4d5d5e3Z4Gd6d7d7e3Z5dS)8Nz"Must be using Python 3.4 or higher)    getLogger)atan2degreessqrt)abspath)get_current_platformDevicelist_device_namesdZev3)OUTPUT_AOUTPUT_BOUTPUT_COUTPUT_DZevbZpistormsZbrickpiZbrickpi3ZfakezUnsupported platform '%s'c@seZdZdZdS)
SpeedValuez
    A base class for other unit types. Don't use this directly; instead, see
    :class:`SpeedPercent`, :class:`SpeedRPS`, :class:`SpeedRPM`,
    :class:`SpeedDPS`, and :class:`SpeedDPM`.
    N)__name__
__module____qualname____doc__rr//usr/lib/python3/dist-packages/ev3dev2/motor.pyrFsrc@s:eZdZdZddZddZddZdS)    SpeedPercentzC
    Speed as a percentage of the motor's maximum rated speed.
    cCs>d|kodkns1tdj|||_dS)NrzE{} is an invalid percentage, must be between -100 and 100 (inclusive)i)AssertionErrorformatpercent)selfrrrr__init__SszSpeedPercent.__init__cCst|jdS)N%)strr)rrrr__str__YszSpeedPercent.__str__cCs|jd|jS)z@
        Return this SpeedPercent in native motor units
        r)r    max_speed)rmotorrrrto_native_units\szSpeedPercent.to_native_unitsN)rrrrrr r#rrrrrNsrc@s:eZdZdZddZddZddZdS)    SpeedNativeUnitsz+
    Speed in tacho counts per second.
    cCs
||_dS)N)
native_counts)rr%rrrrhszSpeedNativeUnits.__init__cCst|jdS)Nz counts/sec)rr%)rrrrr kszSpeedNativeUnits.__str__cCs|jS)z:
        Return this SpeedNativeUnits as a number
        )r%)rr"rrrr#nsz SpeedNativeUnits.to_native_unitsN)rrrrrr r#rrrrr$csr$c@s:eZdZdZddZddZddZdS)    SpeedRPSz(
    Speed in rotations-per-second.
    cCs
||_dS)N)rotations_per_second)rr'rrrryszSpeedRPS.__init__cCst|jdS)Nz rot/sec)rr')rrrrr |szSpeedRPS.__str__cCsNt|j|jks9tdj||j|j|j|j|jS)zf
        Return the native speed measurement required to achieve desired rotations-per-second
        z@invalid rotations-per-second: {} max RPS is {}, {} was requested)absr'max_rpsrrr!)rr"rrrr#s9zSpeedRPS.to_native_unitsN)rrrrrr r#rrrrr&tsr&c@s:eZdZdZddZddZddZdS)    SpeedRPMz(
    Speed in rotations-per-minute.
    cCs
||_dS)N)rotations_per_minute)rr+rrrrszSpeedRPM.__init__cCst|jdS)Nz rot/min)rr+)rrrrr szSpeedRPM.__str__cCsNt|j|jks9tdj||j|j|j|j|jS)zf
        Return the native speed measurement required to achieve desired rotations-per-minute
        z@invalid rotations-per-minute: {} max RPM is {}, {} was requested)r(r+max_rpmrrr!)rr"rrrr#s9zSpeedRPM.to_native_unitsN)rrrrrr r#rrrrr*sr*c@s:eZdZdZddZddZddZdS)    SpeedDPSz&
    Speed in degrees-per-second.
    cCs
||_dS)N)degrees_per_second)rr.rrrrszSpeedDPS.__init__cCst|jdS)Nz deg/sec)rr.)rrrrr szSpeedDPS.__str__cCsNt|j|jks9tdj||j|j|j|j|jS)zd
        Return the native speed measurement required to achieve desired degrees-per-second
        z>invalid degrees-per-second: {} max DPS is {}, {} was requested)r(r.max_dpsrrr!)rr"rrrr#s9zSpeedDPS.to_native_unitsN)rrrrrr r#rrrrr-sr-c@s:eZdZdZddZddZddZdS)    SpeedDPMz&
    Speed in degrees-per-minute.
    cCs
||_dS)N)degrees_per_minute)rr1rrrrszSpeedDPM.__init__cCst|jdS)Nz deg/min)rr1)rrrrr szSpeedDPM.__str__cCsNt|j|jks9tdj||j|j|j|j|jS)zd
        Return the native speed measurement required to achieve desired degrees-per-minute
        z>invalid degrees-per-minute: {} max DPM is {}, {} was requested)r(r1max_dpmrrr!)rr"rrrr#s9zSpeedDPM.to_native_unitsN)rrrrrr r#rrrrr0sr0c seZdZdZdZdZdddddd    d
ddd
ddddddddddddddddddd d!d"d#g Zd$Zd%Zd&Z    d'Z
d(Zd)Zd*Z
d+Zd,Zd+Zd,Zd-Zd.Zd/Zd0Zd1Zd2Zd3Zd4Zd5ed6fd7d8Zed9d:Zed;d<Zejd=d<Zed>d?Zed@dAZ edBdCZ!edDdEZ"edFdGZ#edHdIZ$e$jdJdIZ$edKdLZ%edMdNZ&e&jdOdNZ&edPdQZ'e'jdRdQZ'edSdTZ(e(jdUdTZ(edVdWZ)e)jdXdWZ)edYdZZ*e*jd[dZZ*ed\d]Z+e+jd^d]Z+ed_d`Z,edadbZ-edcddZ.e.jdeddZ.edfdgZ/e/jdhdgZ/edidjZ0e0jdkdjZ0edldmZ1e1jdndmZ1edodpZ2e2jdqdpZ2edrdsZ3e3jdtdsZ3edudvZ4edwdxZ5e5jdydxZ5edzd{Z6ed|d}Z7e7jd~d}Z7ddZ8ddZ9ddZ:ddZ;ddZ<ddZ=ddZ>eddZ?eddZ@eddZAeddZBeddZCd5ddZDd5ddZEd5ddZFd5ddZGd5ddZHddZIddZJddddZKddddZLddddZMddddZNdd6ddZOdddZPeddZQeddZRS)Motora
    The motor class provides a uniform interface for using motors with
    positional and directional feedback such as the EV3 and NXT motors.
    This feedback allows for precise control of the motors. This is the
    most common type of motor, so we just call it `motor`.
    ztacho-motor*_address_command    _commands_count_per_rot_count_per_m_driver_name_duty_cycle_duty_cycle_sp_full_travel_count    _polarity    _position_position_p_position_i_position_d_position_sp
_max_speed_speed    _speed_sp_ramp_up_sp
_ramp_down_sp_speed_p_speed_i_speed_d_state_stop_action
_stop_actions_time_sp_pollr)r,r/r2zrun-foreverzrun-to-abs-poszrun-to-rel-posz    run-timedz
run-directstopresetnormalinversedrunningZrampingZholdingZ
overloadedZstalledcoastbrakeZholdNFcs|dk    r||d<tt|j|j|||d|_d|_d|_d|_d|_d|_    d|_
d|_d|_d|_
d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_t |j!|j"|_#|j#d|_$|j#d|_%|j$d|_&dS)Naddress<ih)'superr3rSYSTEM_CLASS_NAMEr5r6r7r8r9r:r;r<r=r>r?r@rArBrCrDrErFrGrHrIrJrKrLrMrNrOrPfloatr!
count_per_rotr)r,r/r2)rrXname_pattern
name_exactkwargs)    __class__rrr8sF
"                                                                                                                zMotor.__init__cCs"|j|jd\|_}|S)zO
        Returns the name of the port that this motor is connected to.
        rX)get_attr_stringr5)rvaluerrrrX_sz
Motor.addresscCstddS)zp
        Sends a command to the motor controller. See `commands` for a list of
        possible values.
        z!command is a write-only property!N)    Exception)rrrrcommandgsz
Motor.commandcCs|j|jd||_dS)Nre)set_attr_stringr6)rrcrrrreoscCs"|j|jd\|_}|S)a
        Returns a list of commands that are supported by the motor
        controller. Possible values are `run-forever`, `run-to-abs-pos`, `run-to-rel-pos`,
        `run-timed`, `run-direct`, `stop` and `reset`. Not all commands may be supported.

        - `run-forever` will cause the motor to run until another command is sent.
        - `run-to-abs-pos` will run to an absolute position specified by `position_sp`
          and then stop using the action specified in `stop_action`.
        - `run-to-rel-pos` will run to a position relative to the current `position` value.
          The new position will be current `position` + `position_sp`. When the new
          position is reached, the motor will stop using the action specified by `stop_action`.
        - `run-timed` will run the motor for the amount of time specified in `time_sp`
          and then stop the motor using the action specified by `stop_action`.
        - `run-direct` will run the motor at the duty cycle specified by `duty_cycle_sp`.
          Unlike other run commands, changing `duty_cycle_sp` while running *will*
          take effect immediately.
        - `stop` will stop any of the run commands before they are complete using the
          action specified by `stop_action`.
        - `reset` will reset all of the motor parameter attributes to their default value.
          This will also have the effect of stopping the motor.
        commands)get_attr_setr7)rrcrrrrgsszMotor.commandscCs"|j|jd\|_}|S)a
        Returns the number of tacho counts in one rotation of the motor. Tacho counts
        are used by the position and speed attributes, so you can use this value
        to convert rotations or degrees to tacho counts. (rotation motors only)
        r])get_attr_intr8)rrcrrrr]szMotor.count_per_rotcCs"|j|jd\|_}|S)z
        Returns the number of tacho counts in one meter of travel of the motor. Tacho
        counts are used by the position and speed attributes, so you can use this
        value to convert from distance to tacho counts. (linear motors only)
        count_per_m)rir9)rrcrrrrjszMotor.count_per_mcCs"|j|jd\|_}|S)zW
        Returns the name of the driver that provides this tacho motor device.
        driver_name)rbr:)rrcrrrrkszMotor.driver_namecCs"|j|jd\|_}|S)zq
        Returns the current duty cycle of the motor. Units are percent. Values
        are -100 to 100.
        
duty_cycle)rir;)rrcrrrrlszMotor.duty_cyclecCs"|j|jd\|_}|S)z
        Writing sets the duty cycle setpoint. Reading returns the current value.
        Units are in percent. Valid values are -100 to 100. A negative value causes
        the motor to rotate in reverse.
        
duty_cycle_sp)rir<)rrcrrrrmszMotor.duty_cycle_spcCs|j|jd||_dS)Nrm)set_attr_intr<)rrcrrrrmscCs"|j|jd\|_}|S)z
        Returns the number of tacho counts in the full travel of the motor. When
        combined with the `count_per_m` atribute, you can use this value to
        calculate the maximum travel distance of the motor. (linear motors only)
        full_travel_count)rir=)rrcrrrroszMotor.full_travel_countcCs"|j|jd\|_}|S)a-
        Sets the polarity of the motor. With `normal` polarity, a positive duty
        cycle will cause the motor to rotate clockwise. With `inversed` polarity,
        a positive duty cycle will cause the motor to rotate counter-clockwise.
        Valid values are `normal` and `inversed`.
        polarity)rbr>)rrcrrrrpszMotor.polaritycCs|j|jd||_dS)Nrp)rfr>)rrcrrrrpscCs"|j|jd\|_}|S)a%
        Returns the current position of the motor in pulses of the rotary
        encoder. When the motor rotates clockwise, the position will increase.
        Likewise, rotating counter-clockwise causes the position to decrease.
        Writing will set the position to that value.
        position)rir?)rrcrrrrqszMotor.positioncCs|j|jd||_dS)Nrq)rnr?)rrcrrrrqscCs"|j|jd\|_}|S)zA
        The proportional constant for the position PID.
        zhold_pid/Kp)rir@)rrcrrr
position_pszMotor.position_pcCs|j|jd||_dS)Nzhold_pid/Kp)rnr@)rrcrrrrrscCs"|j|jd\|_}|S)z=
        The integral constant for the position PID.
        zhold_pid/Ki)rirA)rrcrrr
position_iszMotor.position_icCs|j|jd||_dS)Nzhold_pid/Ki)rnrA)rrcrrrrsscCs"|j|jd\|_}|S)z?
        The derivative constant for the position PID.
        zhold_pid/Kd)rirB)rrcrrr
position_dszMotor.position_dcCs|j|jd||_dS)Nzhold_pid/Kd)rnrB)rrcrrrrtscCs"|j|jd\|_}|S)a-
        Writing specifies the target position for the `run-to-abs-pos` and `run-to-rel-pos`
        commands. Reading returns the current value. Units are in tacho counts. You
        can use the value returned by `count_per_rot` to convert tacho counts to/from
        rotations or degrees.
        position_sp)rirC)rrcrrrruszMotor.position_spcCs|j|jd||_dS)Nru)rnrC)rrcrrrruscCs"|j|jd\|_}|S)z
        Returns the maximum value that is accepted by the `speed_sp` attribute. This
        may be slightly different than the maximum speed that a particular motor can
        reach - it's the maximum theoretical speed.
        r!)rirD)rrcrrrr!szMotor.max_speedcCs"|j|jd\|_}|S)z
        Returns the current motor speed in tacho counts per second. Note, this is
        not necessarily degrees (although it is for LEGO motors). Use the `count_per_rot`
        attribute to convert this value to RPM or deg/sec.
        speed)rirE)rrcrrrrv%szMotor.speedcCs"|j|jd\|_}|S)a
        Writing sets the target speed in tacho counts per second used for all `run-*`
        commands except `run-direct`. Reading returns the current value. A negative
        value causes the motor to rotate in reverse with the exception of `run-to-*-pos`
        commands where the sign is ignored. Use the `count_per_rot` attribute to convert
        RPM or deg/sec to tacho counts per second. Use the `count_per_m` attribute to
        convert m/s to tacho counts per second.
        speed_sp)rirF)rrcrrrrw/s
zMotor.speed_spcCs|j|jd||_dS)Nrw)rnrF)rrcrrrrw<scCs"|j|jd\|_}|S)a
        Writing sets the ramp up setpoint. Reading returns the current value. Units
        are in milliseconds and must be positive. When set to a non-zero value, the
        motor speed will increase from 0 to 100% of `max_speed` over the span of this
        setpoint. The actual ramp time is the ratio of the difference between the
        `speed_sp` and the current `speed` and max_speed multiplied by `ramp_up_sp`.
        
ramp_up_sp)rirG)rrcrrrrx@s    zMotor.ramp_up_spcCs|j|jd||_dS)Nrx)rnrG)rrcrrrrxLscCs"|j|jd\|_}|S)a
        Writing sets the ramp down setpoint. Reading returns the current value. Units
        are in milliseconds and must be positive. When set to a non-zero value, the
        motor speed will decrease from 0 to 100% of `max_speed` over the span of this
        setpoint. The actual ramp time is the ratio of the difference between the
        `speed_sp` and the current `speed` and max_speed multiplied by `ramp_down_sp`.
        ramp_down_sp)rirH)rrcrrrryPs    zMotor.ramp_down_spcCs|j|jd||_dS)Nry)rnrH)rrcrrrry\scCs"|j|jd\|_}|S)zI
        The proportional constant for the speed regulation PID.
        zspeed_pid/Kp)rirI)rrcrrrspeed_p`sz
Motor.speed_pcCs|j|jd||_dS)Nzspeed_pid/Kp)rnrI)rrcrrrrzhscCs"|j|jd\|_}|S)zE
        The integral constant for the speed regulation PID.
        zspeed_pid/Ki)rirJ)rrcrrrspeed_ilsz
Motor.speed_icCs|j|jd||_dS)Nzspeed_pid/Ki)rnrJ)rrcrrrr{tscCs"|j|jd\|_}|S)zG
        The derivative constant for the speed regulation PID.
        zspeed_pid/Kd)rirK)rrcrrrspeed_dxsz
Motor.speed_dcCs|j|jd||_dS)Nzspeed_pid/Kd)rnrK)rrcrrrr|scCs"|j|jd\|_}|S)z
        Reading returns a list of state flags. Possible flags are
        `running`, `ramping`, `holding`, `overloaded` and `stalled`.
        state)rhrL)rrcrrrr}szMotor.statecCs"|j|jd\|_}|S)a2
        Reading returns the current stop action. Writing sets the stop action.
        The value determines the motors behavior when `command` is set to `stop`.
        Also, it determines the motors behavior when a run command completes. See
        `stop_actions` for a list of possible values.
        stop_action)rbrM)rrcrrrr~szMotor.stop_actioncCs|j|jd||_dS)Nr~)rfrM)rrcrrrr~scCs"|j|jd\|_}|S)a(
        Returns a list of stop actions supported by the motor controller.
        Possible values are `coast`, `brake` and `hold`. `coast` means that power will
        be removed from the motor and it will freely coast to a stop. `brake` means
        that power will be removed from the motor and a passive electrical load will
        be placed on the motor. This is usually done by shorting the motor terminals
        together. This load will absorb the energy from the rotation of the motors and
        cause the motor to stop more quickly than coasting. `hold` does not remove
        power from the motor. Instead it actively tries to hold the motor at the current
        position. If an external force tries to turn the motor, the motor will 'push
        back' to maintain its position.
        stop_actions)rhrN)rrcrrrrszMotor.stop_actionscCs"|j|jd\|_}|S)z
        Writing specifies the amount of time the motor will run when using the
        `run-timed` command. Reading returns the current value. Units are in
        milliseconds.
        time_sp)rirO)rrcrrrrsz
Motor.time_spcCs|j|jd||_dS)Nr)rnrO)rrcrrrrscKs5x"|D]}t||||qW|j|_dS)z5Run the motor until another command is sent.
        N)setattrCOMMAND_RUN_FOREVERre)rr`keyrrrrun_forevers
zMotor.run_forevercKs5x"|D]}t||||qW|j|_dS)zRun to an absolute position specified by `position_sp` and then
        stop using the action specified in `stop_action`.
        N)rCOMMAND_RUN_TO_ABS_POSre)rr`rrrrrun_to_abs_poss
zMotor.run_to_abs_poscKs5x"|D]}t||||qW|j|_dS)zRun to a position relative to the current `position` value.
        The new position will be current `position` + `position_sp`.
        When the new position is reached, the motor will stop using
        the action specified by `stop_action`.
        N)rCOMMAND_RUN_TO_REL_POSre)rr`rrrrrun_to_rel_poss
zMotor.run_to_rel_poscKs5x"|D]}t||||qW|j|_dS)zRun the motor for the amount of time specified in `time_sp`
        and then stop the motor using the action specified by `stop_action`.
        N)rCOMMAND_RUN_TIMEDre)rr`rrrr    run_timeds
zMotor.run_timedcKs5x"|D]}t||||qW|j|_dS)zRun the motor at the duty cycle specified by `duty_cycle_sp`.
        Unlike other run commands, changing `duty_cycle_sp` while running *will*
        take effect immediately.
        N)rCOMMAND_RUN_DIRECTre)rr`rrrr
run_directs
zMotor.run_directcKs5x"|D]}t||||qW|j|_dS)zsStop any of the run commands before they are complete using the
        action specified by `stop_action`.
        N)rCOMMAND_STOPre)rr`rrrrrQs
z
Motor.stopcKs5x"|D]}t||||qW|j|_dS)zReset all of the motor parameter attributes to their default value.
        This will also have the effect of stopping the motor.
        N)r
COMMAND_RESETre)rr`rrrrrRs
zMotor.resetcCs|j|jkS)z*Power is being sent to the motor.
        )
STATE_RUNNINGr})rrrr
is_runningszMotor.is_runningcCs|j|jkS)zYThe motor is ramping up or down and has not yet reached a constant output level.
        )
STATE_RAMPINGr})rrrr
is_rampingszMotor.is_rampingcCs|j|jkS)zRThe motor is not turning, but rather attempting to hold a fixed position.
        )
STATE_HOLDINGr})rrrr
is_holdingszMotor.is_holdingcCs|j|jkS)z?The motor is turning, but cannot reach its `speed_sp`.
        )STATE_OVERLOADEDr})rrrr
is_overloadedszMotor.is_overloadedcCs|j|jkS)z4The motor is not turning when it should be.
        )
STATE_STALLEDr})rrrr
is_stalled
szMotor.is_stalledcCstj}|jdkrd|jdkr<|jd|_tj|_|jj|jtjxc||jrzdS|jj|dkrdn||dk    rgtj||dkrgdSqgWdS)aH
        Blocks until ``cond(self.state)`` is ``True``.  The condition is
        checked when there is an I/O event related to the ``state`` attribute.
        Exits early when ``timeout`` (in milliseconds) is reached.

        Returns ``True`` if the condition is met, and ``False`` if the timeout
        is reached.
        Nr}TiF)    timerPrLZ_attribute_file_openselectZpollregisterZPOLLPRIr})rcondtimeoutZticrrrwaits
"&z
Motor.waitcsjfdd|S)a
        Blocks until ``running`` is not in ``self.state`` or ``stalled`` is in
        ``self.state``.  The condition is checked when there is an I/O event
        related to the ``state`` attribute.  Exits early when ``timeout``
        (in milliseconds) is reached.

        Returns ``True`` if the condition is met, and ``False`` if the timeout
        is reached.

        Example::

            m.wait_until_not_moving()
        csj|kpj|kS)N)rr)r})rrr<lambda><sz-Motor.wait_until_not_moving.<locals>.<lambda>)r)rrr)rrwait_until_not_moving.szMotor.wait_until_not_movingcs|jfdd|S)a{
        Blocks until ``s`` is in ``self.state``.  The condition is checked when
        there is an I/O event related to the ``state`` attribute.  Exits early
        when ``timeout`` (in milliseconds) is reached.

        Returns ``True`` if the condition is met, and ``False`` if the timeout
        is reached.

        Example::

            m.wait_until('stalled')
        cs
|kS)Nr)r})srrrKsz"Motor.wait_until.<locals>.<lambda>)r)rrrr)rr
wait_until>s
zMotor.wait_untilcs|jfdd|S)a
        Blocks until ``s`` is not in ``self.state``.  The condition is checked
        when there is an I/O event related to the ``state`` attribute.  Exits
        early when ``timeout`` (in milliseconds) is reached.

        Returns ``True`` if the condition is met, and ``False`` if the timeout
        is reached.

        Example::

            m.wait_while('running')
        cs
|kS)Nr)r})rrrrZsz"Motor.wait_while.<locals>.<lambda>)r)rrrr)rr
wait_whileMs
zMotor.wait_whilecCsrt|tsed|ko&dknsYtdj|dkrFdn|d|t|}|j|S)NrzM{}{} is an invalid speed percentage, must be between -100 and 100 (inclusive)z: i)
isinstancerrrrr#)rrvZlabelrrr_speed_native_units\s
+zMotor._speed_native_unitscCsj|dkr|n|}t|}tt||jd}tt|}||_||_dS)Nrih)r(introundr]rurw)rrrvZposition_deltarwrrr&_set_rel_position_degrees_and_speed_spfs    z,Motor._set_rel_position_degrees_and_speed_spcCs%|r|j|_n|j|_dS)N)STOP_ACTION_HOLDr~STOP_ACTION_COAST)rrWrrr
_set_brakepszMotor._set_brakeTcCs|dks|dkr3tdj||||j|}|j|d||j||j|r|jddt|jdS)z
        Rotate the motor at ``speed`` for ``rotations``

        ``speed`` can be a percentage or a :class:`ev3dev2.motor.SpeedValue`
        object, enabling use of other units.
        Nz+Either speed ({}) or rotations ({}) is NoneihrUr)    
ValueErrorrrrrrrWAIT_RUNNING_TIMEOUTr)rrv    rotationsrWblockrwrrron_for_rotationsvs

zMotor.on_for_rotationscCs|dks|dkr3tdj||||j|}|j|||j||j|r|jddt|jdS)z
        Rotate the motor at ``speed`` for ``degrees``

        ``speed`` can be a percentage or a :class:`ev3dev2.motor.SpeedValue`
        object, enabling use of other units.
        Nz)Either speed ({}) or degrees ({}) is NonerUr)    rrrrrrrrr)rrvrrWrrwrrron_for_degreess

zMotor.on_for_degreescCs|j|}|s?tjdj|||j|dStt||_||_|j||j    |r|j
ddt|jdS)z
        Rotate the motor at ``speed`` to ``position``

        ``speed`` can be a percentage or a :class:`ev3dev2.motor.SpeedValue`
        object, enabling use of other units.
        z/({}) speed is invalid ({}), motor will not moveNrUr)
rlogwarningrrrrrwrurrrr)rrvrqrWrrrron_to_positions
    

zMotor.on_to_positioncCs|j|}|s|rJtjdj||||j|dStt||_t|d|_|j||j    |r|j
ddt|jdS)z
        Rotate the motor at ``speed`` for ``seconds``

        ``speed`` can be a percentage or a :class:`ev3dev2.motor.SpeedValue`
        object, enabling use of other units.
        zF({}) Either speed ({}) or seconds ({}) is invalid, motor will not moveNirUr)
rrrrrrrrwrrrrr)rrvsecondsrWrrrron_for_secondss


zMotor.on_for_secondscCs|j|}|s?tjdj|||j|dStt||_|j||j|r|j    ddt
|jdS)a%
        Rotate the motor at ``speed`` for forever

        ``speed`` can be a percentage or a :class:`ev3dev2.motor.SpeedValue`
        object, enabling use of other units.

        Note that `block` is False by default, this is different from the
        other `on_for_XYZ` methods.
        z/({}) speed is invalid ({}), motor will not moveNrUr)rrrrrrrrwrrrr)rrvrWrrrrons



zMotor.oncCs|j||jdS)N)rrQ)rrWrrroffs
z    Motor.offcCst|j|jS)N)r\rqr])rrrrrszMotor.rotationscCs|jdS)Nih)r)rrrrrsz
Motor.degrees)Srrrrr[SYSTEM_DEVICE_NAME_CONVENTION    __slots__rrrrrrrZENCODER_POLARITY_NORMALZENCODER_POLARITY_INVERSEDPOLARITY_NORMALPOLARITY_INVERSEDrrrrrrSTOP_ACTION_BRAKErrpropertyrXresetterrgr]rjrkrlrmrorprqrrrsrtrur!rvrwrxryrzr{r|r}r~rrrrrrrrQrRrrrrrrrrrrrrrrrrrrrrrr)rarr3s    '

    




    

    

r3cKs7ttjdtj}ddt|||DS)a
    This is a generator function that enumerates all tacho motors that match
    the provided arguments.

    Parameters:
        name_pattern: pattern that device name should match.
            For example, 'motor*'. Default value: '*'.
        keyword arguments: used for matching the corresponding device
            attributes. For example, driver_name='lego-ev3-l-motor', or
            address=['outB', 'outC']. When argument value
            is a list, then a match against any entry of the list is
            enough.
    /css$|]}td|ddVqdS)r^r_TN)r3).0namerrr    <genexpr>szlist_motors.<locals>.<genexpr>)rr
ZDEVICE_ROOT_PATHr3r[r)r^r`Z
class_pathrrrlist_motorss    rcsFeZdZdZejZdZgZdedfddZS)
LargeMotorz
    EV3/NXT large servo motor.

    Same as :class:`Motor`, except it will only successfully initialize if it finds a "large" motor.
    r4NFcs/tt|j|||dddg|dS)Nrkzlego-ev3-l-motorzlego-nxt-motor)rZrr)rrXr^r_r`)rarrrszLargeMotor.__init__)    rrrrr3r[rrrrr)rarrs
    rcsFeZdZdZejZdZgZdedfddZS)MediumMotorz
    EV3 medium servo motor.

    Same as :class:`Motor`, except it will only successfully initialize if it finds a "medium" motor.
    r4NFcs,tt|j|||ddg|dS)Nrkzlego-ev3-m-motor)rZrr)rrXr^r_r`)rarrr szMediumMotor.__init__)    rrrrr3r[rrrrr)rarrs
    rcsFeZdZdZejZdZgZdedfddZS)ActuonixL1250Motorz
    Actuonix L12 50 linear servo motor.

    Same as :class:`Motor`, except it will only successfully initialize if it finds an Actuonix L12 50 linear servo motor
    zlinear*NFcs,tt|j|||ddg|dS)Nrkzact-l12-ev3-50)rZrr)rrXr^r_r`)rarrr1szActuonixL1250Motor.__init__)    rrrrr3r[rrrrr)rarr%s
    rcsFeZdZdZejZdZgZdedfddZS)ActuonixL12100Motorz
    Actuonix L12 100 linear servo motor.

    Same as :class:`Motor`, except it will only successfully initialize if it finds an Actuonix L12 100 linear servo motor
    zlinear*NFcs,tt|j|||ddg|dS)Nrkzact-l12-ev3-100)rZrr)rrXr^r_r`)rarrrBszActuonixL12100Motor.__init__)    rrrrr3r[rrrrr)rarr6s
    rc
sGeZdZdZdZdZdddddd    d
ddd
dddg
ZdedfddZeddZ    eddZ
e
jddZ
eddZeddZ
eddZed d!Zejd"d!Zed#d$Zejd%d$Zed&d'Zejd(d'Zed)d*Zejd+d*Zed,d-Zed.d/Zejd0d/Zed1d2Zed3d4Zejd5d4Zd6Zd7Zd8Zd9Zd:Zd;Zd<Zd=Zd>d?Zd@dAZ dBdCZ!dDdEZ"S)FDcMotorz
    The DC motor class provides a uniform interface for using regular DC motors
    with no fancy controls or feedback. This includes LEGO MINDSTORMS RCX motors
    and LEGO Power Functions motors.
    zdc-motorzmotor*r5r6r7r:r;r<r>rHrGrLrMrNrONFcs|dk    r||d<tt|j|j|||d|_d|_d|_d|_d|_d|_    d|_
d|_d|_d|_
d|_d|_d|_dS)NrX)rZrrr[r5r6r7r:r;r<r>rHrGrLrMrNrO)rrXr^r_r`)rarrras 
"                                                zDcMotor.__init__cCs"|j|jd\|_}|S)zO
        Returns the name of the port that this motor is connected to.
        rX)rbr5)rrcrrrrXuszDcMotor.addresscCstddS)z
        Sets the command for the motor. Possible values are `run-forever`, `run-timed` and
        `stop`. Not all commands may be supported, so be sure to check the contents
        of the `commands` attribute.
        z!command is a write-only property!N)rd)rrrrre}szDcMotor.commandcCs|j|jd||_dS)Nre)rfr6)rrcrrrrescCs"|j|jd\|_}|S)zW
        Returns a list of commands supported by the motor
        controller.
        rg)rhr7)rrcrrrrgszDcMotor.commandscCs"|j|jd\|_}|S)z
        Returns the name of the motor driver that loaded this device. See the list
        of [supported devices] for a list of drivers.
        rk)rbr:)rrcrrrrkszDcMotor.driver_namecCs"|j|jd\|_}|S)z
        Shows the current duty cycle of the PWM signal sent to the motor. Values
        are -100 to 100 (-100% to 100%).
        rl)rir;)rrcrrrrlszDcMotor.duty_cyclecCs"|j|jd\|_}|S)z
        Writing sets the duty cycle setpoint of the PWM signal sent to the motor.
        Valid values are -100 to 100 (-100% to 100%). Reading returns the current
        setpoint.
        rm)rir<)rrcrrrrmszDcMotor.duty_cycle_spcCs|j|jd||_dS)Nrm)rnr<)rrcrrrrmscCs"|j|jd\|_}|S)z[
        Sets the polarity of the motor. Valid values are `normal` and `inversed`.
        rp)rbr>)rrcrrrrpszDcMotor.polaritycCs|j|jd||_dS)Nrp)rfr>)rrcrrrrpscCs"|j|jd\|_}|S)z
        Sets the time in milliseconds that it take the motor to ramp down from 100%
        to 0%. Valid values are 0 to 10000 (10 seconds). Default is 0.
        ry)rirH)rrcrrrryszDcMotor.ramp_down_spcCs|j|jd||_dS)Nry)rnrH)rrcrrrryscCs"|j|jd\|_}|S)z
        Sets the time in milliseconds that it take the motor to up ramp from 0% to
        100%. Valid values are 0 to 10000 (10 seconds). Default is 0.
        rx)rirG)rrcrrrrxszDcMotor.ramp_up_spcCs|j|jd||_dS)Nrx)rnrG)rrcrrrrxscCs"|j|jd\|_}|S)a
        Gets a list of flags indicating the motor status. Possible
        flags are `running` and `ramping`. `running` indicates that the motor is
        powered. `ramping` indicates that the motor has not yet reached the
        `duty_cycle_sp`.
        r})rhrL)rrcrrrr}sz
DcMotor.statecCstddS)z
        Sets the stop action that will be used when the motor stops. Read
        `stop_actions` to get the list of valid values.
        z%stop_action is a write-only property!N)rd)rrrrr~szDcMotor.stop_actioncCs|j|jd||_dS)Nr~)rfrM)rrcrrrr~scCs"|j|jd\|_}|S)z\
        Gets a list of stop actions. Valid values are `coast`
        and `brake`.
        r)rhrN)rrcrrrrszDcMotor.stop_actionscCs"|j|jd\|_}|S)z
        Writing specifies the amount of time the motor will run when using the
        `run-timed` command. Reading returns the current value. Units are in
        milliseconds.
        r)rirO)rrcrrrrszDcMotor.time_spcCs|j|jd||_dS)Nr)rnrO)rrcrrrrszrun-foreverz    run-timedz
run-directrQrSrTrVrWcKs5x"|D]}t||||qW|j|_dS)z5Run the motor until another command is sent.
        N)rrre)rr`rrrrr(s
zDcMotor.run_forevercKs5x"|D]}t||||qW|j|_dS)zRun the motor for the amount of time specified in `time_sp`
        and then stop the motor using the action specified by `stop_action`.
        N)rrre)rr`rrrrr/s
zDcMotor.run_timedcKs5x"|D]}t||||qW|j|_dS)zRun the motor at the duty cycle specified by `duty_cycle_sp`.
        Unlike other run commands, changing `duty_cycle_sp` while running *will*
        take effect immediately.
        N)rrre)rr`rrrrr7s
zDcMotor.run_directcKs5x"|D]}t||||qW|j|_dS)zsStop any of the run commands before they are complete using the
        action specified by `stop_action`.
        N)rrre)rr`rrrrrQ@s
zDcMotor.stop)#rrrrr[rrrrrXrerrgrkrlrmrpryrxr}r~rrrrrrrrrrrrrrQrr)rarrGsb                    
            
    rc
seZdZdZdZdZdddddd    d
ddd
g
ZdedfddZeddZ    eddZ
e
jddZ
eddZeddZ
e
jddZ
eddZejddZedd Zejd!d Zed"d#Zejd$d#Zed%d&Zejd'd&Zed(d)Zejd*d)Zed+d,Zd-Zd.Zd/Zd0Zd1d2Zd3d4ZS)5
ServoMotorzc
    The servo motor class provides a uniform interface for using hobby type
    servo motors.
    zservo-motorzmotor*r5r6r:
_max_pulse_sp
_mid_pulse_sp
_min_pulse_spr>rC_rate_sprLNFcs|dk    r||d<tt|j|j|||d|_d|_d|_d|_d|_d|_    d|_
d|_d|_d|_
dS)NrX)rZrrr[r5r6r:rrrr>rCrrL)rrXr^r_r`)rarrr_s
"                                    zServoMotor.__init__cCs"|j|jd\|_}|S)zO
        Returns the name of the port that this motor is connected to.
        rX)rbr5)rrcrrrrXpszServoMotor.addresscCstddS)a
        Sets the command for the servo. Valid values are `run` and `float`. Setting
        to `run` will cause the servo to be driven to the position_sp set in the
        `position_sp` attribute. Setting to `float` will remove power from the motor.
        z!command is a write-only property!N)rd)rrrrrexszServoMotor.commandcCs|j|jd||_dS)Nre)rfr6)rrcrrrrescCs"|j|jd\|_}|S)z
        Returns the name of the motor driver that loaded this device. See the list
        of [supported devices] for a list of drivers.
        rk)rbr:)rrcrrrrkszServoMotor.driver_namecCs"|j|jd\|_}|S)a9
        Used to set the pulse size in milliseconds for the signal that tells the
        servo to drive to the maximum (clockwise) position_sp. Default value is 2400.
        Valid values are 2300 to 2700. You must write to the position_sp attribute for
        changes to this attribute to take effect.
        max_pulse_sp)rir)rrcrrrrszServoMotor.max_pulse_spcCs|j|jd||_dS)Nr)rnr)rrcrrrrscCs"|j|jd\|_}|S)a
        Used to set the pulse size in milliseconds for the signal that tells the
        servo to drive to the mid position_sp. Default value is 1500. Valid
        values are 1300 to 1700. For example, on a 180 degree servo, this would be
        90 degrees. On continuous rotation servo, this is the 'neutral' position_sp
        where the motor does not turn. You must write to the position_sp attribute for
        changes to this attribute to take effect.
        mid_pulse_sp)rir)rrcrrrrs
zServoMotor.mid_pulse_spcCs|j|jd||_dS)Nr)rnr)rrcrrrrscCs"|j|jd\|_}|S)a?
        Used to set the pulse size in milliseconds for the signal that tells the
        servo to drive to the miniumum (counter-clockwise) position_sp. Default value
        is 600. Valid values are 300 to 700. You must write to the position_sp
        attribute for changes to this attribute to take effect.
        min_pulse_sp)rir)rrcrrrrszServoMotor.min_pulse_spcCs|j|jd||_dS)Nr)rnr)rrcrrrrscCs"|j|jd\|_}|S)a
        Sets the polarity of the servo. Valid values are `normal` and `inversed`.
        Setting the value to `inversed` will cause the position_sp value to be
        inversed. i.e `-100` will correspond to `max_pulse_sp`, and `100` will
        correspond to `min_pulse_sp`.
        rp)rbr>)rrcrrrrpszServoMotor.polaritycCs|j|jd||_dS)Nrp)rfr>)rrcrrrrpscCs"|j|jd\|_}|S)aX
        Reading returns the current position_sp of the servo. Writing instructs the
        servo to move to the specified position_sp. Units are percent. Valid values
        are -100 to 100 (-100% to 100%) where `-100` corresponds to `min_pulse_sp`,
        `0` corresponds to `mid_pulse_sp` and `100` corresponds to `max_pulse_sp`.
        ru)rirC)rrcrrrruszServoMotor.position_spcCs|j|jd||_dS)Nru)rnrC)rrcrrrruscCs"|j|jd\|_}|S)a    
        Sets the rate_sp at which the servo travels from 0 to 100.0% (half of the full
        range of the servo). Units are in milliseconds. Example: Setting the rate_sp
        to 1000 means that it will take a 180 degree servo 2 second to move from 0
        to 180 degrees. Note: Some servo controllers may not support this in which
        case reading and writing will fail with `-EOPNOTSUPP`. In continuous rotation
        servos, this value will affect the rate_sp at which the speed ramps up or down.
        rate_sp)rir)rrcrrrrs
zServoMotor.rate_spcCs|j|jd||_dS)Nr)rnr)rrcrrrrscCs"|j|jd\|_}|S)z
        Returns a list of flags indicating the state of the servo.
        Possible values are:
        * `running`: Indicates that the motor is powered.
        r})rhrL)rrcrrrr}szServoMotor.staterunr\rSrTcKs5x"|D]}t||||qW|j|_dS)zHDrive servo to the position set in the `position_sp` attribute.
        N)rCOMMAND_RUNre)rr`rrrrrs
zServoMotor.runcKs5x"|D]}t||||qW|j|_dS)z%Remove power from the motor.
        N)r
COMMAND_FLOATre)rr`rrrrr\s
zServoMotor.float)rrrrr[rrrrrXrerrkrrrrprurr}rrrrrr\rr)rarrIsJ            

rc@sfeZdZdddZddZddZddd    Zd
dZdd
ZddZ    ddZ
ddZddZdddZ
dddZddZedddZedddZedd d!Zedd"d#Zed$d%Zddd&d'Zddd(d)Zddd*d+Zddd,d-ZdS).MotorSetNcCsPi|_x7t|jD]#}||}|||j|<qW||_dS)z
        motor_specs is a dictionary such as
        {
            OUTPUT_A : LargeMotor,
            OUTPUT_C : LargeMotor,
        }
        N)motorssortedkeysdesc)rmotor_specsrZ
motor_portmotor_classrrrrs
    
zMotorSet.__init__cCs|jr|jS|jjSdS)N)rrar)rrrrr $s    zMotorSet.__str__cKs|jd|jj}xq|D]i}x`|D]X}|dkr/yt||||Wq/tk
r}z|WYdd}~Xq/Xq/Wq"WdS)Nr)getrvaluesrAttributeError)rr`rr"rerrrset_args+s

zMotorSet.set_argscCs|tjtjf}||ks=td|dj|f|dk    rO|n|jj}x|D]}||_qeWdS)Nz,%s is an invalid polarity choice, must be %sz, )rrrrjoinrrrp)rrprZ
valid_choicesr"rrrset_polarity7s!
zMotorSet.set_polaritycKs|jd|jj}x?|D]7}x.|D]&}|dkr/t||||q/Wq"Wx|D]}|d|_qdWdS)Nrrgre)rrg)rrrrre)rr`rr"rrrr_run_commandAs


zMotorSet._run_commandcKstj|d<|j|dS)Nre)rrr)rr`rrrrNs
zMotorSet.run_forevercKstj|d<|j|dS)Nre)rrr)rr`rrrrRs
zMotorSet.run_to_abs_poscKstj|d<|j|dS)Nre)rrr)rr`rrrrVs
zMotorSet.run_to_rel_poscKstj|d<|j|dS)Nre)rrr)rr`rrrrZs
zMotorSet.run_timedcKstj|d<|j|dS)Nre)rrr)rr`rrrr^s
zMotorSet.run_directcCs@|dk    r|n|jj}x|D]}|jq(WdS)N)rrrR)rrr"rrrrRbs!
zMotorSet.resetcCs@|dk    r|n|jj}x|D]}|jq(WdS)N)rrrQ)rrr"rrrrQhs!
z
MotorSet.stopcCsI|dk    r|n|jj}x!|D]}||jkr(dSq(WdS)NFT)rrr})rrr}r"rrr    _is_statens
!
zMotorSet._is_statecCs|j|tjS)N)rrr)rrrrrrwszMotorSet.is_runningcCs|j|tjS)N)rrr)rrrrrr{szMotorSet.is_rampingcCs|j|tjS)N)rrr)rrrrrrszMotorSet.is_holdingcCs|j|tjS)N)rrr)rrrrrrszMotorSet.is_overloadedcCs|jttjS)N)rrrr)rrrrrszMotorSet.is_stalledcCsF|dk    r|n|jj}x|D]}|j||q(WdS)N)rrr)rrrrr"rrrrs!
z
MotorSet.waitcCsC|dk    r|n|jj}x|D]}|j|q(WdS)N)rrr)rrrr"rrrrs!
zMotorSet.wait_until_not_movingcCsF|dk    r|n|jj}x|D]}|j||q(WdS)N)rrr)rrrrr"rrrrs!
zMotorSet.wait_untilcCsF|dk    r|n|jj}x|D]}|j||q(WdS)N)rrr)rrrrr"rrrrs!
zMotorSet.wait_while)rrrrr rrrrrrrrrRrQrrrrrrrrrrrrrrrrs4

    rc@seZdZdZdeddZddZddZd    d    d
dZd    d    dd
Z    d    d    ddZ
ddZd    ddZdS)MoveTanka'
    Controls a pair of motors simultaneously, via individual speed setpoints for each motor.

    Example:

    .. code:: python

        tank_drive = MoveTank(OUTPUT_A, OUTPUT_B)
        # drive in a turn for 10 rotations of the outer motor
        tank_drive.on_for_rotations(50, 75, 10)
    NcCsX||||i}tj||||j||_|j||_|jj|_dS)N)rrr
left_motorright_motorr!)rZleft_motor_portZright_motor_portrrrrrrrszMoveTank.__init__cCsJ|jjddt|jjddt|jj|jjdS)NrUr)rrrrr)rrrr_blocks
zMoveTank._blockcCs4|jj|d}|jj|d}||fS)N
left_speedright_speed)rrr)rrrrrr_unpack_speeds_to_native_unitssz'MoveTank._unpack_speeds_to_native_unitsTcCs$tj||||d||dS)a
        Rotate the motors at 'left_speed & right_speed' for 'rotations'. Speeds
        can be percentages or any SpeedValue implementation.

        If the left speed is not equal to the right speed (i.e., the robot will
        turn), the motor on the outside of the turn will rotate for the full
        ``rotations`` while the motor on the inside will have its requested
        distance calculated according to the expected turn.
        ihN)rr)rrrrrWrrrrrs
zMoveTank.on_for_rotationsc
Cs|j||\}}|dks<|dkrK|dkrK|}|}    nOt|t|kr|}t|||}    nt|||}|}    |jj|||jj||jj|    ||jj||jj|jj|r
|jdS)a
        Rotate the motors at 'left_speed & right_speed' for 'degrees'. Speeds
        can be percentages or any SpeedValue implementation.

        If the left speed is not equal to the right speed (i.e., the robot will
        turn), the motor on the outside of the turn will rotate for the full
        ``degrees`` while the motor on the inside will have its requested
        distance calculated according to the expected turn.
        rN)rr(rrrrrr)
rrrrrWrleft_speed_native_unitsright_speed_native_unitsZleft_degreesZ
right_degreesrrrrs"
$    

zMoveTank.on_for_degreescCs|j||\}}tt||j_t|d|j_|jj|tt||j_t|d|j_|jj||jj|jj|r|j    dS)z
        Rotate the motors at 'left_speed & right_speed' for 'seconds'. Speeds
        can be percentages or any SpeedValue implementation.
        iN)
rrrrrwrrrrr)rrrrrWrrrrrrrs

zMoveTank.on_for_secondscCsf|j||\}}tt||j_tt||j_|jj|jjdS)z
        Start rotating the motors according to ``left_speed`` and ``right_speed`` forever.
        Speeds can be percentages or any SpeedValue implementation.
        N)rrrrrwrr)rrrrrrrrrs

zMoveTank.oncCs>|jj||jj||jj|jjdS)zd
        Stop both motors immediately. Configure both to brake if ``brake`` is
        set.
        N)rrrrQ)rrWrrrr#s
zMoveTank.off)
rrrrrrrrrrrrrrrrrrs    (rc@sdeZdZdZddddZddddZddddZd    d
ZddZd
S)MoveSteeringa
    Controls a pair of motors simultaneously, via a single "steering" value.

    steering [-100, 100]:
        * -100 means turn left on the spot (right motor at 100% forward, left motor at 100% backward),
        *  0   means drive in a straight line, and
        *  100 means turn right on the spot (left motor at 100% forward, right motor at 100% backward).
    
    "steering" can be any number between -100 and 100.

    Example:

    .. code:: python

        steering_drive = MoveSteering(OUTPUT_A, OUTPUT_B)
        # drive in a turn for 10 rotations of the outer motor
        steering_drive.on_for_rotations(-20, SpeedPercent(75), 10)
    TcCsD|j||\}}tj|t|t||||dS)z
        Rotate the motors according to the provided ``steering``.

        The distance each motor will travel follows the rules of :meth:`MoveTank.on_for_rotations`.
        N)get_speed_steeringrrr$)rsteeringrvrrWrrrrrrrAszMoveSteering.on_for_rotationscCsD|j||\}}tj|t|t||||dS)z
        Rotate the motors according to the provided ``steering``.

        The distance each motor will travel follows the rules of :meth:`MoveTank.on_for_degrees`.
        N)rrrr$)rrrvrrWrrrrrrrJszMoveSteering.on_for_degreescCsD|j||\}}tj|t|t||||dS)z[
        Rotate the motors according to the provided ``steering`` for ``seconds``.
        N)rrrr$)rrrvrrWrrrrrrrSszMoveSteering.on_for_secondscCs;|j||\}}tj|t|t|dS)z[
        Start rotating the motors according to the provided ``steering`` forever.
        N)rrrr$)rrrvrrrrrrZszMoveSteering.oncCs|dkr|dks-tdj||jj|}|}|}dtt|d}|dkr~||9}n
||9}||fS)a
        Calculate the speed_sp for each motor in a pair to achieve the specified
        steering. Note that calling this function alone will not make the
        motors move, it only calculates the speed. A run_* function must be called
        afterwards to make the motors move.

        steering [-100, 100]:
            * -100 means turn left on the spot (right motor at 100% forward, left motor at 100% backward),
            *  0   means drive in a straight line, and
            *  100 means turn right on the spot (left motor at 100% forward, right motor at 100% backward).

        speed:
            The speed that should be applied to the outmost motor (the one
            rotating faster). The speed of the other motor will be computed
            automatically.
        rzC{} is an invalid steering, must be between -100 and 100 (inclusive)2ri)rrrrr(r\)rrrvrrZspeed_factorrrrras

zMoveSteering.get_speed_steeringN)    rrrrrrrrrrrrrr.s        rc@s:eZdZdZddddZeddZdS)MoveJoystickzH
    Used to control a pair of motors via a single joystick vector.
    gY@cCs|r|rtjdSt||||}tt||}|dkr_|d7}||krq|}tj|\}}|||}    |||}
tj|t|    d|j    j
|t|
d|jj
|dS)a
        Convert x,y joystick coordinates to left/right motor speed percentages
        and move the motors.

        This will use a classic "arcade drive" algorithm: a full-forward joystick
        goes straight forward and likewise for full-backward. Pushing the joystick
        all the way to one side will make it turn on the spot in that direction.
        Positions in the middle will control how fast the vehicle moves and how
        sharply it turns.

        "x", "y":
            The X and Y coordinates of the joystick's position, with
            (0,0) representing the center position. X is horizontal and Y is vertical.
        
        max_speed (default 100%):
            A percentage or other SpeedValue, controlling the maximum motor speed.
        
        radius (default 100):
            The radius of the joystick, controlling the range of the input (x, y) values.
            e.g. if "x" and "y" can be between -1 and 1, radius should be set to "1".
        
        Nrihr)rrrmath_degreesrrangle_to_speed_percentagerr$rrr)rxyr!ZradiusZ
vector_lengthangleZinit_left_speed_percentageZinit_right_speed_percentageleft_speed_percentageright_speed_percentagerrrrs

zMoveJoystick.oncCsd|kodknr3d}d|d}ndd|koJdknrld}|dd}|}n+d|kodknr|dd}d|}d}nd|kodknr|dd}d|}d}nd|kodknrq|dd}d|}|d    krA|dd
}d|}q|d    krVd}q|d    d
}d|}n&d|kodknr|dd}    d|    }d}nd|kodknrd}|dd}
d|
}nd|kod
knr|dkr2|dd
}d|d}n5|dkrGd}n |dkrg|dd
}|}|dd}
d|
}ntdj||d|dfS)a
        The following graphic illustrates the **motor power outputs** for the
        left and right motors based on where the joystick is pointing, of the
        form ``(left power, right power)``::

                                     (1, 1)
                                  . . . . . . .
                               .        |        .
                            .           |           .
                   (0, 1) .             |             . (1, 0)
                        .               |               .
                       .                |                 .
                      .                 |                  .
                     .                  |                   .
                    .                   |                   .
                    .                   |     x-axis        .
            (-1, 1) .---------------------------------------. (1, -1)
                    .                   |                   .
                    .                   |                   .
                     .                  |                  .
                      .                 | y-axis          .
                        .               |               .
                  (0, -1) .             |             . (-1, 0)
                            .           |           .
                               .        |        .
                                  . . . . . . .
                                     (-1, -1)


        The joystick is a circle within a circle where the (x, y) coordinates
        of the joystick form an angle with the x-axis.  Our job is to translate
        this angle into the percentage of power that should be sent to each motor.
        For instance if the joystick is moved all the way to the top of the circle
        we want both motors to move forward with 100% power...that is represented
        above by (1, 1).  If the joystick is moved all the way to the right side of
        the circle we want to rotate clockwise so we move the left motor forward 100%
        and the right motor backwards 100%...so (1, -1).  If the joystick is at
        45 degrees then we move apply (1, 0) to move the left motor forward 100% and
        the right motor stays still.

        The 8 points shown above are pretty easy. For the points in between those 8
        we do some math to figure out what the percentages should be. Take 11.25 degrees
        for example. We look at how the motors transition from 0 degrees to 45 degrees:
        - the left motor is 1 so that is easy
        - the right motor moves from -1 to 0

        We determine how far we are between 0 and 45 degrees (11.25 is 25% of 45) so we
        know that the right motor should be 25% of the way from -1 to 0...so -0.75 is the
        percentage for the right motor at 11.25 degrees.
        r-gF@ZgPi@g6@ii;ihgu@zNYou created a circle with more than 360 degrees ({})...that is quite the trickrrrrrrrrrr)rdr)rrrZpercentage_from_45_to_90Zpercentage_from_90_to_135Zpercentage_from_135_to_180Zpercentage_from_180_to_225Zpercentage_from_180_to_202Zpercentage_from_202_to_225Zpercentage_from_225_to_270Zpercentage_from_270_to_315Zpercentage_from_315_to_337Zpercentage_from_337_to_360Zpercentage_from_315_to_360rrrrs\5    
    
    

    

    
    
z&MoveJoystick.angle_to_speed_percentageN)rrrrrstaticmethodrrrrrrs=r)6sysversion_infoSystemErrorrrZloggingrZmathrrrros.pathrZev3dev2r    r
rrrrplatformZev3dev2._platform.ev3r
rrrZev3dev2._platform.evbZev3dev2._platform.pistormsZev3dev2._platform.brickpiZev3dev2._platform.brickpi3Zev3dev2._platform.fakerdrrr$r&r*r-r0r3rrrrrrrrobjectrrrrrrrr<module>s^    %%%%%%3X