From 111cf1d57febc350732bce054e441c1217b0506b Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 11 Apr 2017 19:46:47 -0600 Subject: [PATCH 01/18] created ros node to check fo shutdown signal from power supply --- nodes/signal_shutdown.py | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 nodes/signal_shutdown.py diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py new file mode 100644 index 0000000..d0e2cc2 --- /dev/null +++ b/nodes/signal_shutdown.py @@ -0,0 +1,61 @@ +#!/bin/python +# Simple script for shutting down the raspberry Pi at the press of a button. +# by Inderpreet Singh + +import RPi.GPIO as GPIO +import time +import os +import logging +import rospy + + +def setup_gpio_pins(): + # Use the Broadcom SOC Pin numbers + # Setup the Pin with Internal pullups enabled and PIN in reading mode. + logger.debug('Setting GPIO27 / PIN13 to INPUT PULLUP') + GPIO.setmode(GPIO.BCM) + GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / YEL / SW-COM + + # Turn delay relay on + logger.debug('Setting GPIO22 / PIN15 to OUTPUT HIGH') + GPIO.setup(22, GPIO.OUT) # PIN15 / WHT / CH1 + GPIO.output(22, GPIO.HIGH) + + # Send a stable low signal to the power switch + logger.debug('Setting GPIO17 / PIN11 to OUTPUT LOW') + GPIO.setup(17, GPIO.OUT) # PIN15 / WHT / CH1 + GPIO.output(17, GPIO.LOW) + + +def check_for_shutdown(): + rate = rospy.Rate(10) # 10hz + # Monitor pin for stable signal to safely shutdown + while not rospy.is_shutdown(): + if not GPIO.input(27): + logger.debug('Initiating safe shutdown sequence') + successful_debounce = True + for i in range(5000): + if GPIO.input(27): + logger.debug('Signal interrupted, breaking out of safe shutdown sequence') + successful_debounce = False + break + time.sleep(0.001) + if successful_debounce: + logger.debug('Safely shutting down') + rospy.signal_shutdown("Safely shutting down due to Power Off Button") + time.sleep(5) + os.system("sudo shutdown -r now") + break + rospy.Rate(10) + + +if __name__ == '__main__': + logging.basicConfig() + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + rospy.init_node('signal_shutdown') + setup_gpio_pins() + try: + check_for_shutdown() + except rospy.ROSInterruptException: + pass From d4e082c32aa82abe0b1b388991c2da4152e3195d Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 11 Apr 2017 20:12:29 -0600 Subject: [PATCH 02/18] added signal_shutdown to launch file --- launch/personal_food_computer_v2.launch | 1 + 1 file changed, 1 insertion(+) diff --git a/launch/personal_food_computer_v2.launch b/launch/personal_food_computer_v2.launch index d091387..62d519e 100644 --- a/launch/personal_food_computer_v2.launch +++ b/launch/personal_food_computer_v2.launch @@ -67,4 +67,5 @@ + From 772ec35a60ad494e89aab036647d338ab6987e32 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Wed, 12 Apr 2017 02:37:44 +0000 Subject: [PATCH 03/18] updated settings to test signal_shutdown --- launch/personal_food_computer_v2.launch | 2 +- nodes/signal_shutdown.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) mode change 100644 => 100755 nodes/signal_shutdown.py diff --git a/launch/personal_food_computer_v2.launch b/launch/personal_food_computer_v2.launch index 017e6f4..36c0c4a 100644 --- a/launch/personal_food_computer_v2.launch +++ b/launch/personal_food_computer_v2.launch @@ -1,6 +1,7 @@ + @@ -67,5 +68,4 @@ - diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py old mode 100644 new mode 100755 index d0e2cc2..c8f3985 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -1,12 +1,14 @@ -#!/bin/python +#!/usr/bin/env python # Simple script for shutting down the raspberry Pi at the press of a button. # by Inderpreet Singh +# Adapted by Jake Rye and Bob Davis import RPi.GPIO as GPIO import time import os import logging import rospy +from std_msgs.msg import String def setup_gpio_pins(): @@ -28,7 +30,6 @@ def setup_gpio_pins(): def check_for_shutdown(): - rate = rospy.Rate(10) # 10hz # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): if not GPIO.input(27): @@ -46,7 +47,7 @@ def check_for_shutdown(): time.sleep(5) os.system("sudo shutdown -r now") break - rospy.Rate(10) + rospy.sleep(1.) if __name__ == '__main__': From 3b94174c5f56a8afbb0a6465274c76ddc516428d Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Wed, 12 Apr 2017 15:07:48 -0600 Subject: [PATCH 04/18] updated pin references to use BOARD config --- nodes/signal_shutdown.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index d0e2cc2..cf58470 100644 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -13,18 +13,13 @@ def setup_gpio_pins(): # Use the Broadcom SOC Pin numbers # Setup the Pin with Internal pullups enabled and PIN in reading mode. logger.debug('Setting GPIO27 / PIN13 to INPUT PULLUP') - GPIO.setmode(GPIO.BCM) - GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / YEL / SW-COM + GPIO.setmode(GPIO.BOARD) + GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / BOARD 27 YEL / SW-COM # Turn delay relay on logger.debug('Setting GPIO22 / PIN15 to OUTPUT HIGH') - GPIO.setup(22, GPIO.OUT) # PIN15 / WHT / CH1 - GPIO.output(22, GPIO.HIGH) - - # Send a stable low signal to the power switch - logger.debug('Setting GPIO17 / PIN11 to OUTPUT LOW') - GPIO.setup(17, GPIO.OUT) # PIN15 / WHT / CH1 - GPIO.output(17, GPIO.LOW) + GPIO.setup(15, GPIO.OUT) # PIN15 / BOARD 22 / WHT / CH1 + GPIO.output(15, GPIO.HIGH) def check_for_shutdown(): @@ -44,6 +39,7 @@ def check_for_shutdown(): logger.debug('Safely shutting down') rospy.signal_shutdown("Safely shutting down due to Power Off Button") time.sleep(5) + GPIO.output(15, GPIO.LOW) os.system("sudo shutdown -r now") break rospy.Rate(10) From f3eb9bf938c54b0b483556e3cc39428e60884d23 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Wed, 12 Apr 2017 15:14:00 -0600 Subject: [PATCH 05/18] updated pin reference (fixed typo) --- nodes/signal_shutdown.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index ff54c61..7af8818 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -16,22 +16,22 @@ def setup_gpio_pins(): # Setup the Pin with Internal pullups enabled and PIN in reading mode. logger.debug('Setting GPIO27 / PIN13 to INPUT PULLUP') GPIO.setmode(GPIO.BOARD) - GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / BOARD 27 YEL / SW-COM + GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / BCM 27 YELLOW / SW-COM # Turn delay relay on logger.debug('Setting GPIO22 / PIN15 to OUTPUT HIGH') - GPIO.setup(15, GPIO.OUT) # PIN15 / BOARD 22 / WHT / CH1 + GPIO.setup(15, GPIO.OUT) # PIN15 / BCM 22 / WHITE / CH1 GPIO.output(15, GPIO.HIGH) def check_for_shutdown(): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): - if not GPIO.input(27): + if not GPIO.input(13): logger.debug('Initiating safe shutdown sequence') successful_debounce = True for i in range(5000): - if GPIO.input(27): + if GPIO.input(13): logger.debug('Signal interrupted, breaking out of safe shutdown sequence') successful_debounce = False break From e84f5d22412d13640119f712f5107db0171864de Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Wed, 12 Apr 2017 23:01:27 +0000 Subject: [PATCH 06/18] Added publish signal --- nodes/signal_shutdown.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 7af8818..c85abd0 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -8,7 +8,7 @@ import os import logging import rospy -from std_msgs.msg import String +from std_msgs.msg import Float64 def setup_gpio_pins(): @@ -24,9 +24,10 @@ def setup_gpio_pins(): GPIO.output(15, GPIO.HIGH) -def check_for_shutdown(): +def check_for_shutdown(pub13): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): + pub13.publish(GPIO.input(13)) if not GPIO.input(13): logger.debug('Initiating safe shutdown sequence') successful_debounce = True @@ -41,7 +42,7 @@ def check_for_shutdown(): rospy.signal_shutdown("Safely shutting down due to Power Off Button") time.sleep(5) GPIO.output(15, GPIO.LOW) - os.system("sudo shutdown -r now") + os.system("sudo shutdown now") break rospy.sleep(1.) @@ -51,8 +52,9 @@ def check_for_shutdown(): logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) rospy.init_node('signal_shutdown') + pub13 = rospy.Publisher("/GPIO/13", Float64, queue_size=10) setup_gpio_pins() try: - check_for_shutdown() + check_for_shutdown(pub13) except rospy.ROSInterruptException: pass From b2f1e8f97978c4eb3caddd5f23b0143eecff11b7 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Fri, 21 Apr 2017 13:14:24 -0600 Subject: [PATCH 07/18] Updated debounce to use an average instead of requiring all off signals to be valid. --- nodes/signal_shutdown.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 7af8818..63282e3 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -10,16 +10,23 @@ import rospy from std_msgs.msg import String +# This is needed to account for any erroraneous drops in the shutdown signal +VERIFICATION_TIME_SEC = 3 # Time to wait to verify shutdown signal +SHUTDOWN_SIGNAL_THRESHOLD = 0.98 # Percent of shutdown signals needed to + # signal a shutdown (ranges from 0 to 1) + def setup_gpio_pins(): # Use the Broadcom SOC Pin numbers # Setup the Pin with Internal pullups enabled and PIN in reading mode. - logger.debug('Setting GPIO27 / PIN13 to INPUT PULLUP') + rospy.logdebug('Setting GPIO27 / PIN13 to INPUT PULLUP') GPIO.setmode(GPIO.BOARD) - GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # PIN13 / BCM 27 YELLOW / SW-COM + # PIN13 / BCM 27 YELLOW / SW-COM - Signals Shutdown + GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Turn delay relay on - logger.debug('Setting GPIO22 / PIN15 to OUTPUT HIGH') + # Sends signal to the relay to stay on until this drops low. + rospy.logdebug('Setting GPIO22 / PIN15 to OUTPUT HIGH') GPIO.setup(15, GPIO.OUT) # PIN15 / BCM 22 / WHITE / CH1 GPIO.output(15, GPIO.HIGH) @@ -28,28 +35,31 @@ def check_for_shutdown(): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): if not GPIO.input(13): - logger.debug('Initiating safe shutdown sequence') + rospy.logdebug('Initiating safe shutdown sequence') successful_debounce = True - for i in range(5000): - if GPIO.input(13): - logger.debug('Signal interrupted, breaking out of safe shutdown sequence') - successful_debounce = False - break + input_sum = 0 + for i in range(VERIFICATION_TIME_SEC * 1000): + input_sum += GPIO.input(13) time.sleep(0.001) + avg_signal = input_sum / ( VERIFICATION_TIME_SEC * 1000) + rospy.logdebug('The average signal after {} seconds was {}'.format( + VERIFICATION_TIME_SEC, avg_signal) + if avg_signal < SHUTDOWN_SIGNAL_THRESHOLD: + rospy.logwarn('Signal interrupted, breaking out of safe shutdown sequence') + successful_debounce = False + break + if successful_debounce: - logger.debug('Safely shutting down') - rospy.signal_shutdown("Safely shutting down due to Power Off Button") + rospy.logdebug('Safely shutting down') + rospy.signal_shutdown('Safely shutting down due to Power Off Button') time.sleep(5) GPIO.output(15, GPIO.LOW) - os.system("sudo shutdown -r now") + os.system('sudo shutdown -r now') break rospy.sleep(1.) if __name__ == '__main__': - logging.basicConfig() - logger = logging.getLogger(__name__) - logger.setLevel(logging.DEBUG) rospy.init_node('signal_shutdown') setup_gpio_pins() try: From 37e5e56d51d658831f99f7b0905de2f5aa1dff49 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Fri, 21 Apr 2017 19:31:35 +0000 Subject: [PATCH 08/18] Modified debounce signal from break to continue --- nodes/signal_shutdown.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 15f98e6..d7b7083 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -44,11 +44,11 @@ def check_for_shutdown(pub13): time.sleep(0.001) avg_signal = input_sum / ( VERIFICATION_TIME_SEC * 1000) rospy.logdebug('The average signal after {} seconds was {}'.format( - VERIFICATION_TIME_SEC, avg_signal) + VERIFICATION_TIME_SEC, avg_signal)) if avg_signal < SHUTDOWN_SIGNAL_THRESHOLD: rospy.logwarn('Signal interrupted, breaking out of safe shutdown sequence') successful_debounce = False - break + continue if successful_debounce: rospy.logdebug('Safely shutting down') From d5a2d0a6391ccf4a00a63844233683001dd028a7 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Fri, 21 Apr 2017 19:47:48 +0000 Subject: [PATCH 09/18] Fixed typo in cutoff threshold. --- nodes/signal_shutdown.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index d7b7083..7339374 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -45,7 +45,7 @@ def check_for_shutdown(pub13): avg_signal = input_sum / ( VERIFICATION_TIME_SEC * 1000) rospy.logdebug('The average signal after {} seconds was {}'.format( VERIFICATION_TIME_SEC, avg_signal)) - if avg_signal < SHUTDOWN_SIGNAL_THRESHOLD: + if avg_signal > (1 - SHUTDOWN_SIGNAL_THRESHOLD): # avg_signal should be 0 for 100% valid rospy.logwarn('Signal interrupted, breaking out of safe shutdown sequence') successful_debounce = False continue @@ -61,7 +61,7 @@ def check_for_shutdown(pub13): if __name__ == '__main__': - rospy.init_node('signal_shutdown') + rospy.init_node('signal_shutdown', log_level=rospy.DEBUG) pub13 = rospy.Publisher("/GPIO/13", Float64, queue_size=10) setup_gpio_pins() try: From a3ecd3c8751f507b5bee18efc132f1100ae034db Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Fri, 21 Apr 2017 13:49:53 -0600 Subject: [PATCH 10/18] removed debug flag --- nodes/signal_shutdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 7339374..655c14b 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -61,7 +61,7 @@ def check_for_shutdown(pub13): if __name__ == '__main__': - rospy.init_node('signal_shutdown', log_level=rospy.DEBUG) + rospy.init_node('signal_shutdown') pub13 = rospy.Publisher("/GPIO/13", Float64, queue_size=10) setup_gpio_pins() try: From 72a784e0f0008438395de86b01d5d64c14e2cb72 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 25 Apr 2017 14:19:45 -0600 Subject: [PATCH 11/18] Moved from RPi.GPIO to periphery GPIO library --- nodes/signal_shutdown.py | 24 +++++++++++------------- package.xml | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 655c14b..c134151 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -1,9 +1,9 @@ #!/usr/bin/env python # Simple script for shutting down the raspberry Pi at the press of a button. # by Inderpreet Singh -# Adapted by Jake Rye and Bob Davis +# Adapted by Jake Rye and Bob Davis in April, 2017 -import RPi.GPIO as GPIO +from periphery import GPIO import time import os import logging @@ -20,27 +20,26 @@ def setup_gpio_pins(): # Use the Broadcom SOC Pin numbers # Setup the Pin with Internal pullups enabled and PIN in reading mode. rospy.logdebug('Setting GPIO27 / PIN13 to INPUT PULLUP') - GPIO.setmode(GPIO.BOARD) # PIN13 / BCM 27 YELLOW / SW-COM - Signals Shutdown - GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) + gpio_13 = GPIO(13, "in") # Might need to pull the pin up? # Turn delay relay on # Sends signal to the relay to stay on until this drops low. rospy.logdebug('Setting GPIO22 / PIN15 to OUTPUT HIGH') - GPIO.setup(15, GPIO.OUT) # PIN15 / BCM 22 / WHITE / CH1 - GPIO.output(15, GPIO.HIGH) + gpio_15 = GPIO(15, "out") # PIN15 / BCM 22 / WHITE / CH1 -def check_for_shutdown(pub13): +def check_for_shutdown(): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): - pub13.publish(GPIO.input(13)) - if not GPIO.input(13): + shutdown_signal_pin = gpio_13.read() + rospy.logdebug(shutdown_signal_pin) + if not shutdown_signal_pin: rospy.logdebug('Initiating safe shutdown sequence') successful_debounce = True input_sum = 0 for i in range(VERIFICATION_TIME_SEC * 1000): - input_sum += GPIO.input(13) + input_sum += gpio_13.read() time.sleep(0.001) avg_signal = input_sum / ( VERIFICATION_TIME_SEC * 1000) rospy.logdebug('The average signal after {} seconds was {}'.format( @@ -54,7 +53,7 @@ def check_for_shutdown(pub13): rospy.logdebug('Safely shutting down') rospy.signal_shutdown('Safely shutting down due to Power Off Button') time.sleep(5) - GPIO.output(15, GPIO.LOW) + gpio_15.write(0) os.system("sudo shutdown -h now") break rospy.sleep(1.) @@ -62,9 +61,8 @@ def check_for_shutdown(pub13): if __name__ == '__main__': rospy.init_node('signal_shutdown') - pub13 = rospy.Publisher("/GPIO/13", Float64, queue_size=10) setup_gpio_pins() try: - check_for_shutdown(pub13) + check_for_shutdown() except rospy.ROSInterruptException: pass diff --git a/package.xml b/package.xml index c656674..5b645aa 100644 --- a/package.xml +++ b/package.xml @@ -52,7 +52,7 @@ python-requests python-gevent python-flask - + python-periphery-pip rostest From 7b5d4100f0c6c802767d33c47d87891ca634c3a1 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 25 Apr 2017 16:07:08 -0600 Subject: [PATCH 12/18] Added test case for signal shutdown --- launch/test/test_signal_shutdown.launch | 6 ++++++ test/test_nodes/test_signal_shutdown.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 launch/test/test_signal_shutdown.launch create mode 100644 test/test_nodes/test_signal_shutdown.py diff --git a/launch/test/test_signal_shutdown.launch b/launch/test/test_signal_shutdown.launch new file mode 100644 index 0000000..f7a43f2 --- /dev/null +++ b/launch/test/test_signal_shutdown.launch @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/test_nodes/test_signal_shutdown.py b/test/test_nodes/test_signal_shutdown.py new file mode 100644 index 0000000..e6aa7da --- /dev/null +++ b/test/test_nodes/test_signal_shutdown.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +PKG = 'openag_brain' +NAME = 'test_signal_shutdown' + +import sys +import unittest +import rospy +from std_msgs.msg import Float64 + +from nodes.signal_shutdown import setup_gpio_pins, check_for_shutdown + +class TestSignalShutdown(unittest.TestCase): + """ + Test the signal shutdown module to see if it starts up without errors + """ + + def test_setup(self): + setup_gpio_pins() + + def test_signal_shutdown(self): + check_for_shutdown() + +if __name__ == '__main__': + unittest.main() From 6194c14429dd65bb097b502106d6691bb14c5cc5 Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 25 Apr 2017 16:32:50 -0600 Subject: [PATCH 13/18] modified main section in test file --- test/test_nodes/test_signal_shutdown.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_nodes/test_signal_shutdown.py b/test/test_nodes/test_signal_shutdown.py index e6aa7da..430f50d 100644 --- a/test/test_nodes/test_signal_shutdown.py +++ b/test/test_nodes/test_signal_shutdown.py @@ -20,5 +20,6 @@ def test_setup(self): def test_signal_shutdown(self): check_for_shutdown() -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + import rostest + rostest.rosrun(PKG, NAME, TestSignalShutdown) From d0f38004d795dd6ca5eac9cad67134f0530ed22d Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Tue, 25 Apr 2017 16:49:55 -0600 Subject: [PATCH 14/18] modified gpio pins from global variables to local --- nodes/signal_shutdown.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index c134151..e7b950d 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -27,9 +27,10 @@ def setup_gpio_pins(): # Sends signal to the relay to stay on until this drops low. rospy.logdebug('Setting GPIO22 / PIN15 to OUTPUT HIGH') gpio_15 = GPIO(15, "out") # PIN15 / BCM 22 / WHITE / CH1 + return gpio_13, gpio_15 -def check_for_shutdown(): +def check_for_shutdown(gpio_13, gpio_15): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): shutdown_signal_pin = gpio_13.read() @@ -61,8 +62,8 @@ def check_for_shutdown(): if __name__ == '__main__': rospy.init_node('signal_shutdown') - setup_gpio_pins() + gpio_13, gpio_15 = setup_gpio_pins() try: - check_for_shutdown() + check_for_shutdown(gpio_13, gpio_15) except rospy.ROSInterruptException: pass From 946fbddca5898de55b00a21251272e72900b9794 Mon Sep 17 00:00:00 2001 From: Gordon Date: Fri, 5 May 2017 17:07:42 -0600 Subject: [PATCH 15/18] Updated to address issues with python-periphery package not setting up pins correctly. It isn't functional because initiating a pin as low --- nodes/signal_shutdown.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index e7b950d..681c3cf 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -4,6 +4,7 @@ # Adapted by Jake Rye and Bob Davis in April, 2017 from periphery import GPIO +from periphery.gpio import GPIOError import time import os import logging @@ -15,18 +16,41 @@ SHUTDOWN_SIGNAL_THRESHOLD = 0.98 # Percent of shutdown signals needed to # signal a shutdown (ranges from 0 to 1) +def setup_pin(pin, direction, number_of_attempts=5): + """ + The first attempt to connect to the GPIO pins fails, but the second try succeeds. It appears to be a timing issue in the periphery library. + It first exports to the GPIO pin to connect it and then writes the direction. Writing the direction fails, + because of a permission error. + This function is a work around to try several times to allow the export function to finish creating the class in + /sys/class/gpio/gpio{pin_number} + http://python-periphery.readthedocs.io/en/latest/_modules/periphery/gpio.html#GPIO + returns gpio object for writing or reading. + """ + for _ in range(number_of_attempts): + try: + gpio_pin = GPIO(pin, direction) + break + except GPIOError as e: + rospy.logdebug("Failed to connect to GPIO pin {}. {} attempt.".format(pin, _)) + if _+1 == number_of_attempts: + raise e + time.sleep(0.05) + rospy.loginfo("GPIO Pin {} took {} tries to connect.".format(pin, _ + 1)) + return gpio_pin + def setup_gpio_pins(): # Use the Broadcom SOC Pin numbers # Setup the Pin with Internal pullups enabled and PIN in reading mode. rospy.logdebug('Setting GPIO27 / PIN13 to INPUT PULLUP') # PIN13 / BCM 27 YELLOW / SW-COM - Signals Shutdown - gpio_13 = GPIO(13, "in") # Might need to pull the pin up? + gpio_13 = setup_pin(13, "high") # Pull pin high before watching if it drops low to signal shutdown + gpio_13 = setup_pin(13, "in") # Initializes pin to low, not sure how to set to high and watch to drop low. # Turn delay relay on # Sends signal to the relay to stay on until this drops low. rospy.logdebug('Setting GPIO22 / PIN15 to OUTPUT HIGH') - gpio_15 = GPIO(15, "out") # PIN15 / BCM 22 / WHITE / CH1 + gpio_15 = setup_pin(15, "out") # PIN15 / BCM 22 / WHITE / CH1 return gpio_13, gpio_15 @@ -34,6 +58,7 @@ def check_for_shutdown(gpio_13, gpio_15): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): shutdown_signal_pin = gpio_13.read() + rospy.loginfo(shutdown_signal_pin) rospy.logdebug(shutdown_signal_pin) if not shutdown_signal_pin: rospy.logdebug('Initiating safe shutdown sequence') @@ -54,7 +79,7 @@ def check_for_shutdown(gpio_13, gpio_15): rospy.logdebug('Safely shutting down') rospy.signal_shutdown('Safely shutting down due to Power Off Button') time.sleep(5) - gpio_15.write(0) + gpio_15.write(False) os.system("sudo shutdown -h now") break rospy.sleep(1.) From 54e145c123d3ae3aa9c7179b92bb314005acabaa Mon Sep 17 00:00:00 2001 From: Bob Davis Date: Fri, 5 May 2017 17:40:14 -0600 Subject: [PATCH 16/18] modified to use RPi again --- nodes/signal_shutdown.py | 51 +++++++------------------ test/test_nodes/test_signal_shutdown.py | 1 + 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index 681c3cf..ca812b3 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -1,10 +1,9 @@ #!/usr/bin/env python # Simple script for shutting down the raspberry Pi at the press of a button. # by Inderpreet Singh -# Adapted by Jake Rye and Bob Davis in April, 2017 +# Adapted by Jake Rye and Bob Davis -from periphery import GPIO -from periphery.gpio import GPIOError +import RPi.GPIO as GPIO import time import os import logging @@ -16,56 +15,32 @@ SHUTDOWN_SIGNAL_THRESHOLD = 0.98 # Percent of shutdown signals needed to # signal a shutdown (ranges from 0 to 1) -def setup_pin(pin, direction, number_of_attempts=5): - """ - The first attempt to connect to the GPIO pins fails, but the second try succeeds. It appears to be a timing issue in the periphery library. - It first exports to the GPIO pin to connect it and then writes the direction. Writing the direction fails, - because of a permission error. - This function is a work around to try several times to allow the export function to finish creating the class in - /sys/class/gpio/gpio{pin_number} - http://python-periphery.readthedocs.io/en/latest/_modules/periphery/gpio.html#GPIO - returns gpio object for writing or reading. - """ - for _ in range(number_of_attempts): - try: - gpio_pin = GPIO(pin, direction) - break - except GPIOError as e: - rospy.logdebug("Failed to connect to GPIO pin {}. {} attempt.".format(pin, _)) - if _+1 == number_of_attempts: - raise e - time.sleep(0.05) - rospy.loginfo("GPIO Pin {} took {} tries to connect.".format(pin, _ + 1)) - return gpio_pin - def setup_gpio_pins(): # Use the Broadcom SOC Pin numbers # Setup the Pin with Internal pullups enabled and PIN in reading mode. rospy.logdebug('Setting GPIO27 / PIN13 to INPUT PULLUP') + GPIO.setmode(GPIO.BOARD) # PIN13 / BCM 27 YELLOW / SW-COM - Signals Shutdown - gpio_13 = setup_pin(13, "high") # Pull pin high before watching if it drops low to signal shutdown - gpio_13 = setup_pin(13, "in") # Initializes pin to low, not sure how to set to high and watch to drop low. + GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Turn delay relay on # Sends signal to the relay to stay on until this drops low. rospy.logdebug('Setting GPIO22 / PIN15 to OUTPUT HIGH') - gpio_15 = setup_pin(15, "out") # PIN15 / BCM 22 / WHITE / CH1 - return gpio_13, gpio_15 + GPIO.setup(15, GPIO.OUT) # PIN15 / BCM 22 / WHITE / CH1 + GPIO.output(15, GPIO.HIGH) -def check_for_shutdown(gpio_13, gpio_15): +def check_for_shutdown(pub13): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): - shutdown_signal_pin = gpio_13.read() - rospy.loginfo(shutdown_signal_pin) - rospy.logdebug(shutdown_signal_pin) - if not shutdown_signal_pin: + rospy.logdebug("GPIO13: {}".format(GPIO.input(13))) + if not GPIO.input(13): rospy.logdebug('Initiating safe shutdown sequence') successful_debounce = True input_sum = 0 for i in range(VERIFICATION_TIME_SEC * 1000): - input_sum += gpio_13.read() + input_sum += GPIO.input(13) time.sleep(0.001) avg_signal = input_sum / ( VERIFICATION_TIME_SEC * 1000) rospy.logdebug('The average signal after {} seconds was {}'.format( @@ -79,7 +54,7 @@ def check_for_shutdown(gpio_13, gpio_15): rospy.logdebug('Safely shutting down') rospy.signal_shutdown('Safely shutting down due to Power Off Button') time.sleep(5) - gpio_15.write(False) + GPIO.output(15, GPIO.LOW) os.system("sudo shutdown -h now") break rospy.sleep(1.) @@ -87,8 +62,8 @@ def check_for_shutdown(gpio_13, gpio_15): if __name__ == '__main__': rospy.init_node('signal_shutdown') - gpio_13, gpio_15 = setup_gpio_pins() + setup_gpio_pins() try: - check_for_shutdown(gpio_13, gpio_15) + check_for_shutdown(pub13) except rospy.ROSInterruptException: pass diff --git a/test/test_nodes/test_signal_shutdown.py b/test/test_nodes/test_signal_shutdown.py index 430f50d..1cc9a0e 100644 --- a/test/test_nodes/test_signal_shutdown.py +++ b/test/test_nodes/test_signal_shutdown.py @@ -18,6 +18,7 @@ def test_setup(self): setup_gpio_pins() def test_signal_shutdown(self): + setup_gpio_pins() check_for_shutdown() if __name__ == "__main__": From 76bde1706f0b6b7cc379a1a108a38e09ba46c0ad Mon Sep 17 00:00:00 2001 From: Gordon Date: Fri, 5 May 2017 17:50:28 -0600 Subject: [PATCH 17/18] Removed publish gpio values and replaced with logdebug --- nodes/signal_shutdown.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes/signal_shutdown.py b/nodes/signal_shutdown.py index ca812b3..d62dae4 100755 --- a/nodes/signal_shutdown.py +++ b/nodes/signal_shutdown.py @@ -31,7 +31,7 @@ def setup_gpio_pins(): GPIO.output(15, GPIO.HIGH) -def check_for_shutdown(pub13): +def check_for_shutdown(): # Monitor pin for stable signal to safely shutdown while not rospy.is_shutdown(): rospy.logdebug("GPIO13: {}".format(GPIO.input(13))) @@ -64,6 +64,6 @@ def check_for_shutdown(pub13): rospy.init_node('signal_shutdown') setup_gpio_pins() try: - check_for_shutdown(pub13) + check_for_shutdown() except rospy.ROSInterruptException: pass From 95fa124a4e6cae6a2a5db0e019a59c954eb21978 Mon Sep 17 00:00:00 2001 From: Rikuo Hasegawa Date: Thu, 15 Jun 2017 15:06:25 -0400 Subject: [PATCH 18/18] Revert "Decouple recipe persistence" --- launch/personal_food_computer_v2.launch | 1 - nodes/recipe_persistence.py | 72 ------------------------- 2 files changed, 73 deletions(-) delete mode 100755 nodes/recipe_persistence.py diff --git a/launch/personal_food_computer_v2.launch b/launch/personal_food_computer_v2.launch index e0d374b..d57f01a 100644 --- a/launch/personal_food_computer_v2.launch +++ b/launch/personal_food_computer_v2.launch @@ -29,7 +29,6 @@ - diff --git a/nodes/recipe_persistence.py b/nodes/recipe_persistence.py deleted file mode 100755 index d45124d..0000000 --- a/nodes/recipe_persistence.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/python - -import time -import rospy -from roslib.message import get_message_class -from couchdb import Server - -from openag.db_names import ENVIRONMENTAL_DATA_POINT -from openag.cli.config import config as cli_config -from openag.models import EnvironmentalDataPoint - -from openag_brain.utils import gen_doc_id, read_environment_from_ns -from openag_brain.load_env_var_types import VariableInfo - -# Create a tuple constant of valid environmental variables -# Should these be only environment_variables? -ENVIRONMENTAL_VARIABLES = frozenset( - VariableInfo.from_dict(d) - for d in rospy.get_param("/var_types/environment_variables").itervalues() - ) - -RECIPE_VARIABLES = frozenset( - VariableInfo.from_dict(d) - for d in rospy.get_param("/var_types/recipe_variables").itervalues() - ) - -VALID_VARIABLES = ENVIRONMENTAL_VARIABLES.union(RECIPE_VARIABLES) - - -if __name__ == "__main__": - - rospy.init_node('recipe_persistence') - namespace = rospy.get_namespace() - environment = read_environment_from_ns(namespace) - - # Initialize the database server object - db_server = cli_config["local_server"]["url"] - if not db_server: - raise RuntimeError("No local database specified") - environmental_data_db = Server(db_server)[ENVIRONMENTAL_DATA_POINT] - - def generate_callback(variable): - """ - ROS Subscribers need a callback function to call when a topic gets published to. - This function is a high order function that takes the variable name which is determined at - Subscriber generation time, to create a callback function which takes a topic and persists it to the database. - """ - def desired_callback(desired_data): - timestamp = time.time() - - doc = EnvironmentalDataPoint({ - "environment": environment, - "variable": variable, - "is_desired": True, - "value": desired_data.data, - "timestamp": timestamp - }) - - doc_id = gen_doc_id(timestamp) - environmental_data_db[doc_id] = doc - - return desired_callback - - for variable in VALID_VARIABLES: - rospy.Subscriber( - "~{}/desired".format(variable.name), - get_message_class(variable.type), - generate_callback(variable.name) - ) - - # Keep running until ROS stops - rospy.spin()