1- from .motor import Motor
1+ from .motor import SinglePWMMotor , DualPWMMotor
22from .encoder import Encoder
33from machine import Timer
44from .controller import Controller
55from .pid import PID
6+ import sys
67
78class EncodedMotor :
89
10+ ZERO_EFFORT_BREAK = True
11+ ZERO_EFFORT_COAST = False
12+
913 _DEFAULT_LEFT_MOTOR_INSTANCE = None
1014 _DEFAULT_RIGHT_MOTOR_INSTANCE = None
1115 _DEFAULT_MOTOR_THREE_INSTANCE = None
@@ -14,49 +18,57 @@ class EncodedMotor:
1418 @classmethod
1519 def get_default_encoded_motor (cls , index :int = 1 ):
1620 """
17- Get one of the default XRP v2 motor instances. These are singletons, so only one instance of each of these will ever exist.
21+ Get one of the default XRP motor instances. These are singletons, so only one instance of each of these will ever exist.
1822 Raises an exception if an invalid index is requested.
1923
2024 :param index: The index of the motor to get; 1 for left, 2 for right, 3 for motor 3, 4 for motor 4
2125 :type index: int
2226 """
27+
28+ if "RP2350" in sys .implementation ._machine :
29+ MotorImplementation = DualPWMMotor
30+ else :
31+ MotorImplementation = SinglePWMMotor
32+
2333 if index == 1 :
2434 if cls ._DEFAULT_LEFT_MOTOR_INSTANCE is None :
2535 cls ._DEFAULT_LEFT_MOTOR_INSTANCE = cls (
26- Motor ( 6 , 7 , flip_dir = True ),
27- Encoder (0 , 4 , 5 )
36+ MotorImplementation ( "MOTOR_L_IN_1" , "MOTOR_L_IN_2" , flip_dir = True ),
37+ Encoder (0 , "MOTOR_L_ENCODER_A" , "MOTOR_L_ENCODER_B" )
2838 )
2939 motor = cls ._DEFAULT_LEFT_MOTOR_INSTANCE
3040 elif index == 2 :
3141 if cls ._DEFAULT_RIGHT_MOTOR_INSTANCE is None :
3242 cls ._DEFAULT_RIGHT_MOTOR_INSTANCE = cls (
33- Motor ( 14 , 15 ),
34- Encoder (1 , 12 , 13 )
43+ MotorImplementation ( "MOTOR_R_IN_1" , "MOTOR_R_IN_2" ),
44+ Encoder (1 , "MOTOR_R_ENCODER_A" , "MOTOR_R_ENCODER_B" )
3545 )
3646 motor = cls ._DEFAULT_RIGHT_MOTOR_INSTANCE
3747 elif index == 3 :
3848 if cls ._DEFAULT_MOTOR_THREE_INSTANCE is None :
3949 cls ._DEFAULT_MOTOR_THREE_INSTANCE = cls (
40- Motor ( 2 , 3 ),
41- Encoder (2 , 0 , 1 )
50+ MotorImplementation ( "MOTOR_3_IN_1" , "MOTOR_3_IN_2" , flip_dir = True ),
51+ Encoder (2 , "MOTOR_3_ENCODER_A" , "MOTOR_3_ENCODER_B" )
4252 )
4353 motor = cls ._DEFAULT_MOTOR_THREE_INSTANCE
4454 elif index == 4 :
4555 if cls ._DEFAULT_MOTOR_FOUR_INSTANCE is None :
4656 cls ._DEFAULT_MOTOR_FOUR_INSTANCE = cls (
47- Motor ( 10 , 11 , flip_dir = True ),
48- Encoder (3 , 8 , 9 )
57+ MotorImplementation ( "MOTOR_4_IN_1" , "MOTOR_4_IN_2" ),
58+ Encoder (3 , "MOTOR_4_ENCODER_A" , "MOTOR_4_ENCODER_B" )
4959 )
5060 motor = cls ._DEFAULT_MOTOR_FOUR_INSTANCE
5161 else :
5262 return Exception ("Invalid motor index" )
5363 return motor
5464
55- def __init__ (self , motor : Motor , encoder : Encoder ):
65+ def __init__ (self , motor , encoder : Encoder ):
5666
5767 self ._motor = motor
5868 self ._encoder = encoder
5969
70+ self .brake_at_zero = False
71+
6072 self .target_speed = None
6173 self .DEFAULT_SPEED_CONTROLLER = PID (
6274 kp = 0.035 ,
@@ -71,12 +83,38 @@ def __init__(self, motor: Motor, encoder: Encoder):
7183 # If the update timer is not running, start it at 50 Hz (20ms updates)
7284 self .updateTimer .init (period = 20 , callback = lambda t :self ._update ())
7385
86+
7487 def set_effort (self , effort : float ):
7588 """
7689 :param effort: The effort to set this motor to, from -1 to 1
7790 :type effort: float
7891 """
79- self ._motor .set_effort (effort )
92+ if self .brake_at_zero and effort == 0 :
93+ self .brake ()
94+ else :
95+ self ._motor .set_effort (effort )
96+
97+ # EncodedMotor.set_zero_effort_behavior(EncodedMotor.ZERO_POWER_BRAKE)
98+ def set_zero_effort_behavior (self , brake_at_zero_effort ):
99+ """
100+ Sets the behavior of the motor at 0 effort to either brake (hold position) or coast (free spin)
101+ :param brake_at_zero_effort: Whether or not to brake at 0 effort. Can use EncodedMotor.ZERO_EFFORT_BREAK or EncodedMotor.ZERO_EFFORT_COAST for clarity.
102+ :type brake_at_zero_effort: bool
103+ """
104+ self .brake_at_zero = brake_at_zero_effort
105+
106+ def brake (self ):
107+ """
108+ Causes the motor to resist rotation.
109+ """
110+ # Exact impl of brake depends on which board is being used.
111+ self ._motor .brake ()
112+
113+ def coast (self ):
114+ """
115+ Allows the motor to spin freely.
116+ """
117+ self ._motor .coast ()
80118
81119 def get_position (self ) -> float :
82120 """
0 commit comments