Launching RoverVideeoCoordinator. Added working logging system and set up QSettings instance

This commit is contained in:
2018-01-23 10:22:56 -08:00
parent 60ea2d9339
commit 6270f7380f
6 changed files with 318 additions and 19 deletions

View File

@@ -16,28 +16,96 @@
<component name="CreatePatchCommitExecutor">
<option name="PATCH_PATH" value="" />
</component>
<component name="DockManager">
<window id="1">
<content type="file-editors">
<state>
<leaf>
<file leaf-file-name="RoverVideoReceiverOld.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiverOld.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-888">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#10#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="RoverVideoReceiver.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="50" column="113" selection-start-line="50" selection-start-column="113" selection-end-line="50" selection-end-column="113" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf>
</state>
</content>
</window>
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FavoritesManager">
<favorites_list name="ground_station" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="RoverGroundStation.py" pinned="false" current-in-tab="true">
<file leaf-file-name="RoverGroundStation.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RoverGroundStation.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1860">
<caret line="9" column="17" selection-start-line="9" selection-start-column="17" selection-end-line="9" selection-end-column="17" />
<folding />
<state relative-caret-position="576">
<caret line="86" column="110" selection-start-line="86" selection-start-column="110" selection-end-line="86" selection-end-column="110" />
<folding>
<element signature="e#132#142#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Logger.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="378">
<caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" />
<folding>
<element signature="e#110#134#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="RoverVideoCoordinator.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="864">
<caret line="63" column="25" selection-start-line="63" selection-start-column="25" selection-end-line="63" selection-end-column="25" />
<folding>
<element signature="e#110#152#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py" />
<option value="$PROJECT_DIR$/Framework/LoggingSystems/Logger.py" />
<option value="$PROJECT_DIR$/RoverGroundStation.py" />
<option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py" />
</list>
</option>
</component>
@@ -95,6 +163,56 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Framework" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Framework" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="VideoSystems" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="ground_station" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Framework" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="LoggingSystems" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="Scope" />
@@ -343,7 +461,7 @@
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="File Transfer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32908705" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32908705" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32960325" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.18259023" sideWeight="0.49807587" order="7" side_tool="false" content_ui="tabs" />
@@ -402,7 +520,9 @@
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
<folding>
<element signature="e#132#142#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
@@ -410,17 +530,59 @@
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
<folding>
<element signature="e#132#142#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.PyCharm2016.3/system/remote_sources/-1418177152/1376253408/cv_bridge/core.py" />
<entry file="file://$USER_HOME$/.PyCharm2016.3/system/remote_sources/-1418177152/1376253408/rospy/topics.py" />
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiverOld.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-888">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#10#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="50" column="113" selection-start-line="50" selection-start-column="113" selection-end-line="50" selection-end-column="113" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="378">
<caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" />
<folding>
<element signature="e#110#134#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RoverGroundStation.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1860">
<caret line="9" column="17" selection-start-line="9" selection-start-column="17" selection-end-line="9" selection-end-column="17" />
<folding />
<state relative-caret-position="576">
<caret line="86" column="110" selection-start-line="86" selection-start-column="110" selection-end-line="86" selection-end-column="110" />
<folding>
<element signature="e#132#142#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="864">
<caret line="63" column="25" selection-start-line="63" selection-start-column="25" selection-end-line="63" selection-end-column="25" />
<folding>
<element signature="e#110#152#0" expanded="true" />
</folding>
</state>
</provider>
</entry>

View File

@@ -0,0 +1,127 @@
#####################################
# Imports
#####################################
# Python native imports
from PyQt5 import QtCore
from os import makedirs, rename, walk, unlink
from os.path import exists, getmtime
from os import environ
import logging
from datetime import datetime
#####################################
# Global Variables
#####################################
MAX_NUM_LOG_FILES = 30
#####################################
# Logger Definition
#####################################
class Logger(QtCore.QObject):
def __init__(self, console_output=True):
super(Logger, self).__init__()
# ########## Local class variables ##########
self.console_output = console_output
# ########## Get the settings instance ##########
self.settings = QtCore.QSettings()
# # ########## Get the Pick And Plate instance of the logger ##########
self.logger = logging.getLogger("groundstation")
# ########## Set variables with useful paths ##########
self.appdata_base_directory = environ["HOME"] + "/.groundstation"
self.log_directory = self.appdata_base_directory + "//logs"
self.log_file_path = self.log_directory + "//log.txt"
# ########## Cleanup old log files ##########
self.__cleanup_log_files()
# ########## Set up logger with desired settings ##########
self.__setup_logger()
# ########## Place divider in log file to see new program launch ##########
self.__add_startup_log_buffer_text()
def __setup_logger(self):
# Get the appdata directory and make the log path if it doesn't exist
if not exists(self.log_directory):
makedirs(self.log_directory)
# Set the debugging level
self.logger.setLevel(logging.DEBUG)
# Make a formatter with the log line format wanted
formatter = logging.Formatter(fmt='%(levelname)s : %(asctime)s : %(message)s', datefmt='%m/%d/%y %H:%M:%S')
# Set up a file handler so everything can be saved and attach it to the logger
file_handler = logging.FileHandler(filename=self.log_file_path)
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG)
self.logger.addHandler(file_handler)
# Enable console output if requested
if self.console_output:
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
console_handler.setLevel(logging.DEBUG)
self.logger.addHandler(console_handler)
def __cleanup_log_files(self):
# This copies the existing log.txt file to an old version with a datetime stamp
# It then checks if there are too many log files, and if so, deletes the oldest
if exists(self.log_directory):
# Get the number of log files
num_log_files = self.__get_num_files_in_directory(self.log_directory)
# Check that we actually have log files
if num_log_files > 0:
date_time = datetime.now().strftime("%Y%m%d-%H%M%S")
# If we do, move the current logfile to a backup in the format old_log_datetime
if exists(self.log_file_path):
rename(self.log_file_path, self.log_directory + "\\old_log_" + date_time + ".txt")
# If we have more than the max log files delete the oldest one
if num_log_files >= MAX_NUM_LOG_FILES:
unlink(self.__get_name_of_oldest_file(self.log_directory))
def __add_startup_log_buffer_text(self):
# Prints a header saying when the program started
self.logger.info("########## Application Starting ##########")
@staticmethod
def __get_name_of_oldest_file(input_path):
oldest_file_path = None
previous_oldest_time = 0
# Walk the directory passed in to get all folders and files
for dir_path, dir_names, file_names in walk(input_path):
# Go through all of the filenames found
for file in file_names:
# Recreate the full path and get the modified time of the file
current_path = dir_path + "\\" + file
time = getmtime(current_path)
# Default case for if the variables above have not been initially set
if previous_oldest_time == 0:
previous_oldest_time = time
oldest_file_path = current_path
# Saves the oldest time and file path of the current file if it's older (lower timestamp) than the
# last file saved in the variables
if time < previous_oldest_time:
previous_oldest_time = time
oldest_file_path = current_path
# Returns the path to the oldest file after checking all the files
return oldest_file_path
@staticmethod
def __get_num_files_in_directory(input_path):
# Walk the directory passed in to get all the files
for _, _, file_names in walk(input_path):
# Return the number of files found in the directory
return len(file_names)

View File

@@ -24,9 +24,9 @@ FONT = cv2.FONT_HERSHEY_TRIPLEX
#####################################
# RoverVideoReceiver Class Definition
#####################################
class RoverVideoReceiver(QtCore.QThread):
class RoverVideoCoordinator(QtCore.QThread):
def __init__(self, shared_objects):
super(RoverVideoReceiver, self).__init__()
super(RoverVideoCoordinator, self).__init__()
# ########## Reference to class init variables ##########
self.shared_objects = shared_objects
@@ -47,12 +47,22 @@ class RoverVideoReceiver(QtCore.QThread):
def run(self):
self.logger.debug("Starting Video Coordinator Thread")
topics = rospy.get_published_topics("/cameras")
for group in topics:
main_topic = group[0]
last_section_topic = main_topic.split("/")[-1]
if "image_" in main_topic and "zed" not in main_topic and last_section_topic == "compressed" :
print group[0]
while self.run_thread_flag:
self.msleep(100)
self.logger.debug("Stopping Video Coordinator Thread")
def _get_cameras(self):
def connect_signals_and_slots(self):
pass

View File

@@ -50,12 +50,6 @@ class RoverVideoReceiver(QtCore.QThread):
# self.video_subscriber = rospy.Subscriber(self.topic_path, CompressedImage,
# self.__image_data_received_callback) # type: rospy.Subscriber
topics = rospy.get_published_topics(self.topic_path)
for group in topics:
if "image_" in group[0]:
print group[0]
self.subscription_queue_size = 10
# Steam name variable
@@ -103,7 +97,6 @@ class RoverVideoReceiver(QtCore.QThread):
self.image_ready_signal.emit()
self.new_frame = False
def __on_image_update_ready(self):
self.video_display_label.setPixmap(self.pixmap)

View File

@@ -10,6 +10,7 @@ import rospy
import qdarkstyle
# Custom Imports
import Framework.LoggingSystems.Logger as Logger
import Framework.VideoSystems.RoverVideoCoordinator as RoverVideoCoordinator
#####################################
@@ -80,8 +81,10 @@ class GroundStation(QtCore.QObject):
self.RIGHT_SCREEN_ID) # type: ApplicationWindow
# ##### Instantiate Simple Classes #####
self.logger_setup_class = Logger.Logger(console_output=True) # Doesn't need to be shared
# ##### Instantiate Threaded Classes #####
self.__add_thread("Video Coordinator", RoverVideoCoordinator.RoverVideoCoordinator(self.shared_objects))
# self.__add_thread("Primary Video",
# RoverVideoReceiver.RoverVideoReceiver(
@@ -152,6 +155,10 @@ if __name__ == "__main__":
application = QtWidgets.QApplication(sys.argv) # Create the ase qt gui application
application.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
QtCore.QCoreApplication.setOrganizationName("OSURC")
QtCore.QCoreApplication.setOrganizationDomain("http://osurobotics.club/")
QtCore.QCoreApplication.setApplicationName("groundstation")
ground_station = GroundStation()
application.exec_() # Execute launching of the application