Week 5. Sep 19.26 2018 - michelle-qin/Portfolio GitHub Wiki

Working on UI "Start." Components (open/close gate, on/off staircase, home/top ramp) work independently/separately, but not together in the process of "Start."

1st issue: Staircase was not turning off at initialization (i.e. moment user presses "Start") Went into initialization method, saw "self.turnOnStaircase(OFF)" which logically was correct. Went to the top of main.py file and saw "OFF = TRUE" and "ON = FALSE" Strange logic. Not sure why author of code assigned it that way. So, I modified code to use universal term of "False". See below.

def initialize(self):
    self.openGate(CLOSE)
    self.turnOnStaircase(False)
    self.homeRamp(HOME)

Fixed the issue. Staircase turns off at initialization.

2nd issue: Staircase is turning on/off at random intervals. Reconvened with Mr. Harlow. Objective: turn on staircase once ramp goes back home; turn off staircase when marble returns to ramp. Modified code according to objective. Replaced "ON" and "OFF" with "True" and "False, respectively. See below.

def auto(self):
    self.ids.auto.text = "Stop"
    self.ids.auto.color = 0.180, 0.188, 0.980, 1
    
    self.initialize()
    sleep(1)
    #if (self.isBallAtBottomOfRamp()):
    self.homeRamp(TOP)
    sleep(1)
    
    
    self.homeRamp(HOME)
    
    self.turnOnStaircase(False)
   
    sleep(1)
    self.turnOnStaircase(True)
    sleep(2.5)
    self.openGate(OPEN)
    sleep(1.5)
    #self.openGate(CLOSE)
    self.turnOnStaircase(False)
    self.openGate(False)
    self.ids.auto.text = "Start"

3rd issue: Reverse logic.

Staircase turn on/off was reversed. Switched RPiMIB PWM calls. See below:

def turnOnStaircase(self, isOn):
    if (isOn == True):
        print('staircase on')
        #RPiMIB.sendPWM(5, 0)
        RPiMIB.sendPWM(5, int(self.staircaseSpeed) * 100)
    else: 
        print('staircase off')
        #RPiMIB.sendPWM(5, int(self.staircaseSpeed) * 125)
        RPiMIB.sendPWM(5, 0)
    self.isStaircaseOn = isOn

Similarly, gate open/close was reversed. Switched RPiMIB PWM calls. See below:

def openGate(self, isOpen):
    if (isOpen == OPEN):
        self.ids.gate.text = "Close Gate"
        print('close gate')
        RPiMIB.sendPWM(4, 4000)
    else:
        self.ids.gate.text = "Open Gate"
        print('open gate')
        RPiMIB.sendPWM(4, 1000)
    self.isGateOpen = isOpen

Why I didn't realize this earlier: when testing the separate components, I had to press the corresponding button twice to open the gate or turn on staircase. At the time, I thought it would be a small issue that I would fix later. But, it explains why the staircase was turning on/off and the gate was opening/closing at undesired times. Now that I fixed it, the individual buttons correspond with action (e.g. when I press "Close Gate" once, the gate closes).

4th issue: Button for "Staircase" only showed "Staircase On" - wouldn't change Realized turnOnStaircase method was missing the "self.ids.staircase.text" line that the gate & ramp had. Updated code see below.

def turnOnStaircase(self, isOn):
    if (isOn == True):
        self.ids.staircase.text = "Staircase Off" #Michelle added this
        print('staircase on')
        #RPiMIB.sendPWM(5, 0)
        RPiMIB.sendPWM(5, int(self.staircaseSpeed) * 100)
    else: 
        self.ids.staircase.text = "Staircase On" #Michelle added this
        print('staircase off')
        #RPiMIB.sendPWM(5, int(self.staircaseSpeed) * 125)
        RPiMIB.sendPWM(5, 0)
    self.isStaircaseOn = isOn

5th issue: when working with the individual gate component, the gate wouldn't fully close when I pressed the button for it to (it would come close, but still leave a gap). Changed value from 1000 to 500 - fixed the problem. Updated code see below:

def openGate(self, isOpen):
    if (isOpen == OPEN):
        self.ids.gate.text = "Close Gate"
        print('close gate')
        RPiMIB.sendPWM(4, 4000)
    else:
        self.ids.gate.text = "Open Gate"
        print('open gate')
        RPiMIB.sendPWM(4, 500)
    self.isGateOpen = isOpen

6th issue: each time I run the file, the staircase slowly moves before pressing any buttons. Worked with partner Albert to figure out what's wrong. We traced back to see which method is called when the file is run. Narrowed it down to MyApp().run(). Initial thought was to add a line to that method to turn off the staircase/initialize. Realized that wouldn't work, because the method wouldn't recognize "self" since the "self" would be representing that class. Then, we added random lines of "self.initialize()" throughout the code - our logic was that somewhere, we need to initialize (i.e. turn off staircase, close gate, ramp to home) when the code is run so the staircase would't be moving slowly.

After troubleshooting, found a commented out method called "def init(self, **kwargs" already written in the code. See below:

def __init__(self, **kwargs):
    self.initialize()

Seemed like it was describing what we wanted it to do, so we uncommented the method, tried running it, and ran into error. Continued to face troubleshooting - googled "init kivy screen manager", went into slackoverflow and realized we were missing a line " super(Screen,self).init(**kwargs)". Added it to the code and it worked. See updated code below.

def __init__(self, **kwargs):
    super(Screen,self).__init__(**kwargs)
    self.initialize()

Why we need that super line: there's a default "init" method in the code. If we want to change it, we need to override it using super.

7th issue: the individual gate and staircase buttons would sometimes not work on the 1st toggle (when you press the button the first and second time after running the file). Logic in code seemed fine, and the hardware all matched up. Worked with mentor Nikolai to figure it out. It ended up working when we toggled it twice. Updated code see below.

def toggleGate(self):
    self.ids.gate.color = 0.701, 0.560, 0.078, 1
    print("[debug]", self.isGateOpen)
    #self.isGateOpen = not self.isGateOpen
    self.openGate(not self.isGateOpen)
    #sleep(0.2)
    self.openGate(not self.isGateOpen)
    #sleep(0.2)
    self.openGate(not self.isGateOpen)

(same for toggleStaircase)

The logic is the same, but we've just added two more lines to toggle it one more time. We think the reason might be because it delays the process a little so the program can understand it. Along the way, I learned a more efficient way to synthesize the code. Instead of writing (isOn == False), it's more clear to leave it as (isOn).