@@ -8,6 +8,7 @@ class Robot:
88 from ev3dev2 .sensor import INPUT_1 , INPUT_2 , INPUT_3 , INPUT_4
99 from ev3dev2 .sound import Sound
1010 from ev3dev2 .button import Button
11+ from ev3dev2 .led import Leds , LED_COLORS , LED_DEFAULT_COLOR , LED_GROUPS , LEDS
1112 import math
1213
1314 def __init__ (self , filename ):
@@ -19,6 +20,8 @@ def __init__(self, filename):
1920
2021 self .spkr = self .Sound ()
2122 self .btn = self .Button ()
23+ self .led = self .Leds ()
24+
2225 self .LeftMotor = eval (conf .get ('Drivebase' , 'LeftMotorPort' ))
2326 self .RightMotor = eval (conf .get ('Drivebase' , 'RightMotorPort' ))
2427 self .WheelCircumference = float (conf .get ('Drivebase' , 'WheelCircumference' ))
@@ -54,6 +57,9 @@ def __init__(self, filename):
5457 self .lm = LargeMotor (self .LeftMotor )
5558 self .rm = LargeMotor (self .RightMotor )
5659
60+ self .gs ._ensure_mode (self .gs .MODE_GYRO_G_A )
61+ self .cs ._ensure_mode (self .cs .MODE_COL_REFLECT )
62+
5763 if self .MotorInverted ^ (self .GearRatio / abs (self .GearRatio ) == - 1 ):
5864 self .lm .polarity = "inversed"
5965 self .rm .polarity = "inversed"
@@ -68,7 +74,6 @@ def __init__(self, filename):
6874 else :
6975 self .GyroInvertedNum = 1
7076
71- #self.spkr.speak("Robot object instantiated")
7277 self .spkr .beep ()
7378
7479 def reflectCal (self ):
@@ -86,19 +91,20 @@ def reflectCal(self):
8691 reflRate = 100 / (reflHighVal - reflLowVal )
8792
8893 @property
89- def correctedReflectedLightIntensity (self ):
94+ def correctedRLI (self ):
9095 value = min ([100 , max ([0 , (self .cs .reflected_light_intensity * reflRate ) + (- reflLowVal * reflRate )])])
9196 return (value )
9297
98+ @property
9399 def correctedAngle (self ):
94100 # Multiply the gyro angle by -1 if the gyro is mounted upside-down relative to the motors in the robot.
95101 # GyroInvertedNum is set up in __init__()
96- return (self .gs .angle * self .GyroInvertedNum )
102+ return (self .gs .angle_and_rate [ 0 ] * self .GyroInvertedNum )
97103
98104 def zeroGyro (self ):
99105 # Reset the gyro angle to zero by switching modes. gyro.reset would have been used instead of this function, but it does not work
100106 self .gs ._ensure_mode (self .gs .MODE_GYRO_RATE )
101- self .gs ._ensure_mode (self .gs .MODE_GYRO_ANG )
107+ self .gs ._ensure_mode (self .gs .MODE_GYRO_G_A )
102108
103109 def DriveAtHeading (self , Heading , Distance , Speed , Stop ):
104110 """
@@ -131,24 +137,32 @@ def DriveAtHeading(self, Heading, Distance, Speed, Stop):
131137 right_motor_now = self .rm .degrees
132138 left_motor_change = left_motor_now - left_motor_start
133139 right_motor_change = right_motor_now - right_motor_start
140+
141+ # Determine the sign of the speed, for PID correction
134142 sign = Speed / abs (Speed )
143+
135144 # Find number of degrees that motors need to rotate to reach the desired number of cm.
136145 target = (Distance * 360 ) / self .WheelCircumference
146+
137147 # Find the average of the left and right encoders, as they could be different from PID correction
138148 avg = abs ((left_motor_change + right_motor_change ) / 2 )
149+
139150 # Initialize variables for PID control
140151 integral = 0.0
141152 last_error = 0.0
142153 derivative = 0.0
154+
143155 # Check if the motors have gone far enough
144156 while avg < target :
145157 # Read the gyro
146- current_angle = self .correctedAngle ()
158+ current_angle = self .correctedAngle
159+
147160 # Calculate the PID components
148161 error = current_angle - Heading
149162 integral = integral + error
150163 derivative = error - last_error
151164 last_error = error
165+
152166 # Calculate Steering value based on PID components and kp, ki, and kd
153167 turn_native_units = sign * max ([min ([(self .kp * error ) + (self .ki * integral ) + (self .kd * derivative ), 100 ]), - 100 ])
154168
@@ -189,17 +203,17 @@ def degrees2power(self, currentDifference):
189203 def GyroTurn (self , Heading ):
190204 sign = 1
191205
192- if Heading - self .correctedAngle () == 0 :
206+ if Heading - self .correctedAngle == 0 :
193207 return
194208
195- currentHeading = self .correctedAngle ()
209+ currentHeading = self .correctedAngle
196210 while (currentHeading > 0.5 + Heading ) or (currentHeading < Heading - 0.5 ):
197211 currentDifference = Heading - currentHeading
198212 if ((sign > 0 ) and (currentDifference < 0 )) or ((sign < 0 ) and (currentDifference > 0 )):
199213 sign *= - 1
200214 power = sign * self .degrees2power (currentDifference )
201215 self .tank .on (power , - 1 * power )
202- currentHeading = self .correctedAngle ()
216+ currentHeading = self .correctedAngle
203217 self .tank .stop ()
204218
205219 def ArcTurn (self , Degrees , Radius , Speed ):
@@ -214,18 +228,18 @@ def ArcTurn(self, Degrees, Radius, Speed):
214228 return
215229 math .fmod (Degrees , 360 )
216230
217- startHeading = self .correctedAngle ()
231+ startHeading = self .correctedAngle
218232
219233 if ((Degrees > 0 ) and (Speed > 0 )) or ((Degrees < 0 ) and (Speed < 0 )):
220234 self .tank .on (Speed , (Radius - self .WidthBetweenWheels ) * Speed / Radius )
221235 else :
222236 self .tank .on ((Radius - self .WidthBetweenWheels ) * Speed / Radius , Speed )
223237
224238 if Degrees > 0 :
225- while (self .correctedAngle () - startHeading ) < Degrees :
239+ while (self .correctedAngle - startHeading ) < Degrees :
226240 dummy = 1
227241 else :
228- while (self .correctedAngle () - startHeading ) > Degrees :
242+ while (self .correctedAngle - startHeading ) > Degrees :
229243 dummy = 1
230244
231245 self .tank .stop ()
@@ -256,7 +270,7 @@ def DriveBump(self, Heading, Speed):
256270 derivative = 0.0
257271
258272 # Read the gyro
259- current_angle = self .correctedAngle ()
273+ current_angle = self .correctedAngle
260274
261275 # Calculate the PID components
262276 error = current_angle - Heading
@@ -281,7 +295,7 @@ def DriveBump(self, Heading, Speed):
281295 # Check if the motors have slowed down (because the robot hit something)
282296 while avgSpd > 0.90 * target :
283297 # Read the gyro
284- current_angle = self .correctedAngle ()
298+ current_angle = self .correctedAngle
285299
286300 # Calculate the PID components
287301 error = current_angle - Heading
@@ -358,18 +372,23 @@ def LineStop(self, Heading, Speed, Stop):
358372 Speed = - 75
359373 print ("Speed must be between -75 and 75 (inclusive)." )
360374
375+ # Check and store the sign of the input speed for PID correction
361376 sign = Speed / abs (Speed )
362377
378+ # Set the brick light to solid amber
379+ #EV3.SetLEDColor("ORANGE", "NORMAL")
363380
364-
365- # Initialize variables for PID control
381+ # Initialize variables for PID control and end checking
366382 integral = 0.0
367383 last_error = 0.0
368384 derivative = 0.0
385+ end = False
386+ seenWhite = False
387+
369388 # Check if the motors have gone far enough
370- while avg < target :
389+ while not end :
371390 # Read the gyro
372- current_angle = self .correctedAngle ()
391+ current_angle = self .correctedAngle
373392
374393 # Calculate the PID components
375394 error = current_angle - Heading
@@ -381,8 +400,20 @@ def LineStop(self, Heading, Speed, Stop):
381400 turn_native_units = sign * max ([min ([(self .kp * error ) + (self .ki * integral ) + (self .kd * derivative ), 100 ]), - 100 ])
382401
383402 # Start the motors, using the steering value calculated by the PID control, and the input speed multiplied by speedMult (0 - 1, see above).
384- self .steer .on (- turn_native_units , (Speed * speedMult ))
403+ self .steer .on (- turn_native_units , (Speed ))
404+
405+ # Check if the sensor is seeing white
406+ if self .correctedRLI >= 95 :
407+ self .spkr .beep (play_type = 1 )
408+ seenWhite = True
409+ elif (self .correctedRLI <= 10 ) and seenWhite :
410+ end = True
411+ else :
412+ seenWhite = False
385413
386- # If the robot is to stop, stop the motors. Otherwise, leave the motors on and return .
414+ # If the robot is to stop, stop the motors. Otherwise, leave the motors on.
387415 if not Stop == False :
388- self .steer .stop ()
416+ self .steer .stop ()
417+
418+ # Set the brick light back to green flashing
419+ #EVS.SetLEDColor("GREEN", "PULSE")
0 commit comments