1
+ # The program doesn't work without this. Not sure why.
1
2
from ev3dev2 .motor import *
2
3
from ev3dev2 .sensor .lego import *
3
4
from ev3dev2 .sensor import *
5
+
6
+ # Global Variables for color sensor calibration
4
7
reflHighVal = 100
5
8
reflLowVal = 0
6
9
reflRate = 1
7
10
8
11
class Robot :
12
+ # Import stuff
9
13
from ev3dev2 .motor import MoveTank , OUTPUT_A , OUTPUT_B , OUTPUT_C , OUTPUT_D , LargeMotor
10
14
from ev3dev2 .sensor .lego import ColorSensor , GyroSensor , InfraredSensor , TouchSensor , UltrasonicSensor
11
15
from ev3dev2 .sensor import INPUT_1 , INPUT_2 , INPUT_3 , INPUT_4
@@ -16,60 +20,88 @@ class Robot:
16
20
import ev3dev2 .fonts as fonts
17
21
import math
18
22
19
-
20
23
def __init__ (self , filename ):
24
+ """
25
+ Stores all the properties of the robot, such as wheel circumference, motor ports, ect. Also provides methods for higher-level
26
+ interaction with the robot, such as driving in a straight line at a specific heading, following a line, or driving until hitting
27
+ an obstacle. Also instantiates motor and sensor objects for direct use later, if necessary.
28
+ Reads ``filename`` for robot properties; ``filename`` should be a .ini or .cfg file in INI format. See the current robot.cfg
29
+ for format example.
30
+ """
31
+ # Load and read the config file
21
32
from configparser import SafeConfigParser
22
33
conf = SafeConfigParser ()
23
34
conf .read (filename )
24
35
36
+ # Set the "ForFLL" flag based on it's status in the config file (used in some input validation)
25
37
self .ForFLL = bool (conf .get ('Other' , 'ForFLL' ) == "TRUE" )
26
38
39
+ # Instantiate objects for controlling things on the brick itself (Speaker, Buttons, Lights, and the LCD)
27
40
self .spkr = self .Sound ()
28
41
self .btn = self .Button ()
29
42
self .led = self .Leds ()
30
43
self .disp = self .Display ()
31
44
45
+ # Read the drive motor ports from the config file, and store. "eval()" is used because the port names "OUTPUT_#",
46
+ # where # is a capital letter, A - D, are variables used as constants, and reading as a string does not work.
32
47
self .LeftMotor = eval (conf .get ('Drivebase' , 'LeftMotorPort' ))
33
48
self .RightMotor = eval (conf .get ('Drivebase' , 'RightMotorPort' ))
49
+ # Read and store the wheel circumference and width between the wheels
34
50
self .WheelCircumference = float (conf .get ('Drivebase' , 'WheelCircumference' ))
35
51
self .WidthBetweenWheels = float (conf .get ('Drivebase' , 'WidthBetweenWheels' ))
52
+ # Read and store MotorInverted and GyroInverted. GyroInverted shoould be true if the gyro is inverted relative to the motors,
53
+ # and MotorInverted should be true if the drive motors are upside-down. Drive functions will not work correctly if these
54
+ # values are incorrect, and they are the first things to check if the drive functions do not work correctly.
36
55
self .MotorInverted = bool (conf .get ('Drivebase' , 'MotorInverted' ) == "TRUE" )
37
- self .GearRatio = float (conf .get ('Drivebase' , 'GearRatio' ))
38
56
self .GyroInverted = bool (conf .get ('Drivebase' , 'GyroInverted' ) == "TRUE" )
57
+ # Reads and stores the gear ratio value. Currently not used, except for motor direction.
58
+ # (1 and -1 work, with -1 meaning a 1:1 ratio that reverses the motor direction)
59
+ self .GearRatio = float (conf .get ('Drivebase' , 'GearRatio' ))
60
+ # Reads and stores the PID gains for driving in a straight line.
39
61
self .kp = float (conf .get ('Drivebase' , 'kp' ))
40
62
self .ki = float (conf .get ('Drivebase' , 'ki' ))
41
63
self .kd = float (conf .get ('Drivebase' , 'kd' ))
42
64
65
+ # Read the sensor ports from the config file, and store. "eval()" is used because the port names "INPUT_#",
66
+ # where # is a number, 1 - 4, are variables used as constants, and reading as a string does not work.
43
67
self .ColorPort = eval (conf .get ('Sensors' , 'ColorPort' ))
44
68
self .GyroPort = eval (conf .get ('Sensors' , 'GyroPort' ))
45
69
self .InfraredPort = eval (conf .get ('Sensors' , 'InfraredPort' ))
46
70
self .TouchPort = eval (conf .get ('Sensors' , 'TouchPort' ))
47
71
self .UltrasonicPort = eval (conf .get ('Sensors' , 'UltrasonicPort' ))
72
+ # Reads and stores the PID gains for following a line.
48
73
self .kpLine = float (conf .get ('Sensors' , 'kpLine' ))
49
74
self .kiLine = float (conf .get ('Sensors' , 'kiLine' ))
50
75
self .kdLine = float (conf .get ('Sensors' , 'kdLine' ))
51
76
77
+ # Read the auxillary motor ports, if any, from the config file, and store. "eval()" is used because the port names "OUTPUT_#",
78
+ # where # is a capital letter, A - D, are variables used as constants, and reading as a string does not work.
52
79
self .AuxMotor1 = eval (conf .get ('AuxMotors' , 'AuxMotor1' ))
53
80
self .AuxMotor2 = eval (conf .get ('AuxMotors' , 'AuxMotor2' ))
54
81
82
+ # Instantiate the auxillary motor objects (only if motors are connected)
55
83
#self.m1 = MediumMotor(self.AuxMotor1)
56
84
#self.m2 = MediumMotor(self.AuxMotor2)
57
85
58
86
87
+ # Instantiate the sensor objects
59
88
self .cs = ColorSensor (self .ColorPort )
60
89
self .gs = GyroSensor (self .GyroPort )
61
90
self .ir = InfraredSensor (self .InfraredPort )
62
91
self .us = UltrasonicSensor (self .UltrasonicPort )
63
92
93
+ # Instantiate the drive motor objecta, as well as the motorset objects for controlling both simultainiously
64
94
self .tank = MoveTank (self .LeftMotor , self .RightMotor )
65
- self .tank .gyro = GyroSensor (self .GyroPort )
66
95
self .steer = MoveSteering (self .LeftMotor , self .RightMotor )
67
96
self .lm = LargeMotor (self .LeftMotor )
68
97
self .rm = LargeMotor (self .RightMotor )
69
98
99
+ # Reset the gyro angle to zero by switching modes
70
100
self .gs ._ensure_mode (self .gs .MODE_GYRO_G_A )
71
101
self .cs ._ensure_mode (self .cs .MODE_COL_REFLECT )
72
102
103
+ # If the motors are inverted xor the gear ratio is negative, set the motor poloraity to be inverted,
104
+ # so normal motor commands will run the motors in the opposite direction.
73
105
if self .MotorInverted ^ (self .GearRatio / abs (self .GearRatio ) == - 1 ):
74
106
self .lm .polarity = "inversed"
75
107
self .rm .polarity = "inversed"
@@ -79,11 +111,14 @@ def __init__(self, filename):
79
111
self .rm .polarity = "normal"
80
112
self .tank .set_polarity = "normal"
81
113
114
+ # Set the integer GyroInvertedNum to reflect the boolean GyroInverted, with -1 = True, and 1 = False,
115
+ # for use in calculations later
82
116
if self .GyroInverted :
83
117
self .GyroInvertedNum = - 1
84
118
else :
85
119
self .GyroInvertedNum = 1
86
120
121
+ # Beep to signify the robot isdone initialization (it takes a while)
87
122
self .spkr .beep ()
88
123
89
124
def reflectCal (self ):
0 commit comments