1+ # The program doesn't work without this. Not sure why.
12from ev3dev2 .motor import *
23from ev3dev2 .sensor .lego import *
34from ev3dev2 .sensor import *
5+
6+ # Global Variables for color sensor calibration
47reflHighVal = 100
58reflLowVal = 0
69reflRate = 1
710
811class Robot :
12+ # Import stuff
913 from ev3dev2 .motor import MoveTank , OUTPUT_A , OUTPUT_B , OUTPUT_C , OUTPUT_D , LargeMotor
1014 from ev3dev2 .sensor .lego import ColorSensor , GyroSensor , InfraredSensor , TouchSensor , UltrasonicSensor
1115 from ev3dev2 .sensor import INPUT_1 , INPUT_2 , INPUT_3 , INPUT_4
@@ -16,60 +20,88 @@ class Robot:
1620 import ev3dev2 .fonts as fonts
1721 import math
1822
19-
2023 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
2132 from configparser import SafeConfigParser
2233 conf = SafeConfigParser ()
2334 conf .read (filename )
2435
36+ # Set the "ForFLL" flag based on it's status in the config file (used in some input validation)
2537 self .ForFLL = bool (conf .get ('Other' , 'ForFLL' ) == "TRUE" )
2638
39+ # Instantiate objects for controlling things on the brick itself (Speaker, Buttons, Lights, and the LCD)
2740 self .spkr = self .Sound ()
2841 self .btn = self .Button ()
2942 self .led = self .Leds ()
3043 self .disp = self .Display ()
3144
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.
3247 self .LeftMotor = eval (conf .get ('Drivebase' , 'LeftMotorPort' ))
3348 self .RightMotor = eval (conf .get ('Drivebase' , 'RightMotorPort' ))
49+ # Read and store the wheel circumference and width between the wheels
3450 self .WheelCircumference = float (conf .get ('Drivebase' , 'WheelCircumference' ))
3551 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.
3655 self .MotorInverted = bool (conf .get ('Drivebase' , 'MotorInverted' ) == "TRUE" )
37- self .GearRatio = float (conf .get ('Drivebase' , 'GearRatio' ))
3856 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.
3961 self .kp = float (conf .get ('Drivebase' , 'kp' ))
4062 self .ki = float (conf .get ('Drivebase' , 'ki' ))
4163 self .kd = float (conf .get ('Drivebase' , 'kd' ))
4264
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.
4367 self .ColorPort = eval (conf .get ('Sensors' , 'ColorPort' ))
4468 self .GyroPort = eval (conf .get ('Sensors' , 'GyroPort' ))
4569 self .InfraredPort = eval (conf .get ('Sensors' , 'InfraredPort' ))
4670 self .TouchPort = eval (conf .get ('Sensors' , 'TouchPort' ))
4771 self .UltrasonicPort = eval (conf .get ('Sensors' , 'UltrasonicPort' ))
72+ # Reads and stores the PID gains for following a line.
4873 self .kpLine = float (conf .get ('Sensors' , 'kpLine' ))
4974 self .kiLine = float (conf .get ('Sensors' , 'kiLine' ))
5075 self .kdLine = float (conf .get ('Sensors' , 'kdLine' ))
5176
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.
5279 self .AuxMotor1 = eval (conf .get ('AuxMotors' , 'AuxMotor1' ))
5380 self .AuxMotor2 = eval (conf .get ('AuxMotors' , 'AuxMotor2' ))
5481
82+ # Instantiate the auxillary motor objects (only if motors are connected)
5583 #self.m1 = MediumMotor(self.AuxMotor1)
5684 #self.m2 = MediumMotor(self.AuxMotor2)
5785
5886
87+ # Instantiate the sensor objects
5988 self .cs = ColorSensor (self .ColorPort )
6089 self .gs = GyroSensor (self .GyroPort )
6190 self .ir = InfraredSensor (self .InfraredPort )
6291 self .us = UltrasonicSensor (self .UltrasonicPort )
6392
93+ # Instantiate the drive motor objecta, as well as the motorset objects for controlling both simultainiously
6494 self .tank = MoveTank (self .LeftMotor , self .RightMotor )
65- self .tank .gyro = GyroSensor (self .GyroPort )
6695 self .steer = MoveSteering (self .LeftMotor , self .RightMotor )
6796 self .lm = LargeMotor (self .LeftMotor )
6897 self .rm = LargeMotor (self .RightMotor )
6998
99+ # Reset the gyro angle to zero by switching modes
70100 self .gs ._ensure_mode (self .gs .MODE_GYRO_G_A )
71101 self .cs ._ensure_mode (self .cs .MODE_COL_REFLECT )
72102
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.
73105 if self .MotorInverted ^ (self .GearRatio / abs (self .GearRatio ) == - 1 ):
74106 self .lm .polarity = "inversed"
75107 self .rm .polarity = "inversed"
@@ -79,11 +111,14 @@ def __init__(self, filename):
79111 self .rm .polarity = "normal"
80112 self .tank .set_polarity = "normal"
81113
114+ # Set the integer GyroInvertedNum to reflect the boolean GyroInverted, with -1 = True, and 1 = False,
115+ # for use in calculations later
82116 if self .GyroInverted :
83117 self .GyroInvertedNum = - 1
84118 else :
85119 self .GyroInvertedNum = 1
86120
121+ # Beep to signify the robot isdone initialization (it takes a while)
87122 self .spkr .beep ()
88123
89124 def reflectCal (self ):
0 commit comments