Added check for ros master on startup. More work on video coordinator.

This commit is contained in:
2018-01-23 12:54:01 -08:00
parent 6270f7380f
commit 03706408d3
6 changed files with 209 additions and 91 deletions

View File

@@ -24,8 +24,8 @@
<file leaf-file-name="RoverVideoReceiverOld.py" pinned="false" current-in-tab="false"> <file leaf-file-name="RoverVideoReceiverOld.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiverOld.py"> <entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiverOld.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-888"> <state relative-caret-position="282">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="44" column="45" selection-start-line="44" selection-start-column="42" selection-end-line="44" selection-end-column="68" />
<folding> <folding>
<element signature="e#0#10#0" expanded="true" /> <element signature="e#0#10#0" expanded="true" />
</folding> </folding>
@@ -36,8 +36,8 @@
<file leaf-file-name="RoverVideoReceiver.py" pinned="false" current-in-tab="true"> <file leaf-file-name="RoverVideoReceiver.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py"> <entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306"> <state relative-caret-position="540">
<caret line="50" column="113" selection-start-line="50" selection-start-column="113" selection-end-line="50" selection-end-column="113" /> <caret line="45" column="8" selection-start-line="45" selection-start-column="8" selection-end-line="45" selection-end-column="47" />
<folding /> <folding />
</state> </state>
</provider> </provider>
@@ -54,22 +54,10 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<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="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"> <file leaf-file-name="Logger.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py"> <entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="378"> <state relative-caret-position="-162">
<caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" /> <caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" />
<folding> <folding>
<element signature="e#110#134#0" expanded="true" /> <element signature="e#110#134#0" expanded="true" />
@@ -78,11 +66,11 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="RoverVideoCoordinator.py" pinned="false" current-in-tab="true"> <file leaf-file-name="RoverVideoCoordinator.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py"> <entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="864"> <state relative-caret-position="-312">
<caret line="63" column="25" selection-start-line="63" selection-start-column="25" selection-end-line="63" selection-end-column="25" /> <caret line="42" column="8" selection-start-line="42" selection-start-column="8" selection-end-line="43" selection-end-column="56" />
<folding> <folding>
<element signature="e#110#152#0" expanded="true" /> <element signature="e#110#152#0" expanded="true" />
</folding> </folding>
@@ -90,6 +78,18 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="RoverGroundStation.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/RoverGroundStation.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="624">
<caret line="167" column="43" selection-start-line="167" selection-start-column="43" selection-end-line="167" selection-end-column="43" />
<folding>
<element signature="e#132#142#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf> </leaf>
</component> </component>
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
@@ -102,10 +102,11 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py" />
<option value="$PROJECT_DIR$/Framework/LoggingSystems/Logger.py" /> <option value="$PROJECT_DIR$/Framework/LoggingSystems/Logger.py" />
<option value="$PROJECT_DIR$/RoverGroundStation.py" />
<option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py" /> <option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py" />
<option value="$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py" />
<option value="$PROJECT_DIR$/Framework/StartupSystems/ROSMasterChecker.py" />
<option value="$PROJECT_DIR$/RoverGroundStation.py" />
</list> </list>
</option> </option>
</component> </component>
@@ -209,7 +210,7 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="LoggingSystems" /> <option name="myItemId" value="StartupSystems" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
@@ -455,16 +456,17 @@
<frame x="0" y="0" width="1920" height="1044" extended-state="6" /> <frame x="0" y="0" width="1920" height="1044" extended-state="6" />
<editor active="true" /> <editor active="true" />
<layout> <layout>
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.134375" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="TODO" 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="6" side_tool="false" content_ui="tabs" /> <window_info id="TODO" 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="6" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32916668" sideWeight="0.50192416" order="7" side_tool="true" content_ui="tabs" /> <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32916668" sideWeight="0.50192416" order="7" side_tool="true" content_ui="tabs" />
<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="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="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.32908705" 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="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" /> <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" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.134375" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<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="Find" 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="1" 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="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" /> <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
@@ -472,7 +474,6 @@
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" /> <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" /> <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Find" 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="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" 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="Ant Build" active="false" anchor="right" 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" />
</layout> </layout>
<layout-to-restore> <layout-to-restore>
@@ -540,25 +541,25 @@
<entry file="file://$USER_HOME$/.PyCharm2016.3/system/remote_sources/-1418177152/1376253408/rospy/topics.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"> <entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiverOld.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-888"> <state relative-caret-position="282">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> <caret line="44" column="45" selection-start-line="44" selection-start-column="42" selection-end-line="44" selection-end-column="68" />
<folding> <folding>
<element signature="e#0#10#0" expanded="true" /> <element signature="e#0#10#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py"> <entry file="file://$USER_HOME$/.PyCharm2016.2/system/remote_sources/-1418177152/1376253408/rospy/client.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306"> <state relative-caret-position="196">
<caret line="50" column="113" selection-start-line="50" selection-start-column="113" selection-end-line="50" selection-end-column="113" /> <caret line="349" column="4" selection-start-line="349" selection-start-column="4" selection-end-line="349" selection-end-column="4" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py"> <entry file="file://$PROJECT_DIR$/Framework/LoggingSystems/Logger.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="378"> <state relative-caret-position="-162">
<caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" /> <caret line="21" column="37" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="37" />
<folding> <folding>
<element signature="e#110#134#0" expanded="true" /> <element signature="e#110#134#0" expanded="true" />
@@ -566,26 +567,44 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-312">
<caret line="42" column="8" selection-start-line="42" selection-start-column="8" selection-end-line="43" selection-end-column="56" />
<folding>
<element signature="e#110#152#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RoverGroundStation.py"> <entry file="file://$PROJECT_DIR$/RoverGroundStation.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="576"> <state relative-caret-position="624">
<caret line="86" column="110" selection-start-line="86" selection-start-column="110" selection-end-line="86" selection-end-column="110" /> <caret line="167" column="43" selection-start-line="167" selection-start-column="43" selection-end-line="167" selection-end-column="43" />
<folding> <folding>
<element signature="e#132#142#0" expanded="true" /> <element signature="e#132#142#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoCoordinator.py"> <entry file="file://$PROJECT_DIR$/Framework/StartupSystems/ROSMasterChecker.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="864"> <state relative-caret-position="774">
<caret line="63" column="25" selection-start-line="63" selection-start-column="25" selection-end-line="63" selection-end-column="25" /> <caret line="43" column="38" selection-start-line="43" selection-start-column="38" selection-end-line="43" selection-end-column="38" />
<folding> <folding>
<element signature="e#110#152#0" expanded="true" /> <element signature="e#110#152#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/Framework/VideoSystems/RoverVideoReceiver.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="540">
<caret line="45" column="8" selection-start-line="45" selection-start-column="8" selection-end-line="45" selection-end-column="47" />
<folding />
</state>
</provider>
</entry>
</component> </component>
<component name="webServersAuthStorage"> <component name="webServersAuthStorage">
<data>AAAAsC92Kuu3oLrABnhEDJd2fqLpSLKMDnz1RoGljcqcyx6rWWvT/BV+wcLNHGnvYk97nqnk/pKm4cGIiar9MRU3nZkNwyjJxPVtt3haC8iDCZdLJZ6CmktPYqrohRIav09rau96cPFO/I//1EIneIP/1ljcNiibrP6ukAATwUH19NLQaGz1/EYXXVq+qowSGeFE7dAFp107pLkmub5CsKj/8zF+PCqHoF8AEDn937Vn/JpXGWVGlieBMxMrucAQD8JqIA==</data> <data>AAAAsC92Kuu3oLrABnhEDJd2fqLpSLKMDnz1RoGljcqcyx6rWWvT/BV+wcLNHGnvYk97nqnk/pKm4cGIiar9MRU3nZkNwyjJxPVtt3haC8iDCZdLJZ6CmktPYqrohRIav09rau96cPFO/I//1EIneIP/1ljcNiibrP6ukAATwUH19NLQaGz1/EYXXVq+qowSGeFE7dAFp107pLkmub5CsKj/8zF+PCqHoF8AEDn937Vn/JpXGWVGlieBMxMrucAQD8JqIA==</data>

View File

@@ -0,0 +1,45 @@
#####################################
# Imports
#####################################
# Python native imports
from PyQt5 import QtCore, QtGui, QtWidgets
import time
import logging
import socket
import rospy
# Custom Imports
#####################################
# Global Variables
#####################################
#####################################
# RoverVideoReceiver Class Definition
#####################################
class ROSMasterChecker(QtCore.QThread):
def __init__(self):
super(ROSMasterChecker, self).__init__()
# ########## Class Variables ##########
self.ros_master_present = False
self.start_time = time.time()
self.start()
def run(self):
try:
master = rospy.get_master()
master.getPid()
self.ros_master_present = True
except socket.error:
return
def master_present(self, timeout):
while self.isRunning() and (time.time() - self.start_time) < timeout:
self.msleep(100)
return self.ros_master_present

View File

@@ -14,15 +14,17 @@ from cv_bridge import CvBridge
from sensor_msgs.msg import CompressedImage from sensor_msgs.msg import CompressedImage
# Custom Imports # Custom Imports
import RoverVideoReceiver
##################################### #####################################
# Global Variables # Global Variables
##################################### #####################################
FONT = cv2.FONT_HERSHEY_TRIPLEX CAMERA_TOPIC_PATH = "/cameras"
EXCLUDED_CAMERAS = ["zed"]
##################################### #####################################
# RoverVideoReceiver Class Definition # RoverVideoCoordinator Class Definition
##################################### #####################################
class RoverVideoCoordinator(QtCore.QThread): class RoverVideoCoordinator(QtCore.QThread):
def __init__(self, shared_objects): def __init__(self, shared_objects):
@@ -44,24 +46,59 @@ class RoverVideoCoordinator(QtCore.QThread):
# ########## Thread Flags ########## # ########## Thread Flags ##########
self.run_thread_flag = True self.run_thread_flag = True
self.setup_cameras_flag = True
# ########## Class Variables ##########
self.global_start_signal = None
self.global_connect_signals_and_slots_signal = None
self.global_kill_signal = None
self.valid_cameras = []
self.camera_threads = {}
# ########## Setup cameras ##########
self.__get_cameras()
self.__setup_video_threads()
def run(self): def run(self):
self.logger.debug("Starting Video Coordinator Thread") 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: while self.run_thread_flag:
if self.setup_cameras_flag:
self.setup_cameras_flag = False
self.msleep(100) self.msleep(100)
self.__wait_for_camera_threads()
self.logger.debug("Stopping Video Coordinator Thread") self.logger.debug("Stopping Video Coordinator Thread")
def _get_cameras(self): def __get_cameras(self):
topics = rospy.get_published_topics(CAMERA_TOPIC_PATH)
names = []
for topics_group in topics:
main_topic = topics_group[0]
camera_name = main_topic.split("/")[2]
names.append(camera_name)
names = set(names)
for camera in EXCLUDED_CAMERAS:
if camera in names:
names.remove(camera)
self.valid_cameras = list(names)
def __setup_video_threads(self):
for camera in self.valid_cameras:
self.camera_threads[camera] = RoverVideoReceiver.RoverVideoReceiver(camera)
def __wait_for_camera_threads(self):
for camera in self.camera_threads:
self.camera_threads[camera].wait()
def connect_signals_and_slots(self): def connect_signals_and_slots(self):
pass pass
@@ -71,5 +108,9 @@ class RoverVideoCoordinator(QtCore.QThread):
signals_and_slots_signal.connect(self.connect_signals_and_slots) signals_and_slots_signal.connect(self.connect_signals_and_slots)
kill_signal.connect(self.on_kill_threads_requested__slot) kill_signal.connect(self.on_kill_threads_requested__slot)
for camera in self.camera_threads:
self.camera_threads[camera].setup_signals(start_signal, signals_and_slots_signal, kill_signal)
def on_kill_threads_requested__slot(self): def on_kill_threads_requested__slot(self):
self.run_thread_flag = False self.run_thread_flag = False

View File

@@ -28,13 +28,11 @@ class RoverVideoReceiver(QtCore.QThread):
publish_message_signal = QtCore.pyqtSignal() publish_message_signal = QtCore.pyqtSignal()
image_ready_signal = QtCore.pyqtSignal() image_ready_signal = QtCore.pyqtSignal()
def __init__(self, shared_objects, video_display_label, topic_path): def __init__(self, camera_name):
super(RoverVideoReceiver, self).__init__() super(RoverVideoReceiver, self).__init__()
# ########## Reference to class init variables ########## # ########## Reference to class init variables ##########
self.shared_objects = shared_objects self.camera_name = camera_name
self.video_display_label = video_display_label # type:QtWidgets.QLabel
self.topic_path = topic_path
# ########## Get the settings instance ########## # ########## Get the settings instance ##########
self.settings = QtCore.QSettings() self.settings = QtCore.QSettings()
@@ -46,14 +44,13 @@ class RoverVideoReceiver(QtCore.QThread):
self.run_thread_flag = True self.run_thread_flag = True
# ########## Class Variables ########## # ########## Class Variables ##########
self.camera_title_name = self.camera_name.replace("_", " ").title()
self.topic_path = "/cameras/" + self.camera_name + "/image_640x360/compressed"
# Subscription variables # Subscription variables
# self.video_subscriber = rospy.Subscriber(self.topic_path, CompressedImage, self.video_subscriber = rospy.Subscriber(self.topic_path, CompressedImage,
# self.__image_data_received_callback) # type: rospy.Subscriber self.__image_data_received_callback) # type: rospy.Subscriber
self.subscription_queue_size = 10
# Steam name variable
self.video_name = self.topic_path.split("/")[2].replace("_", " ").title()
# Image variables # Image variables
self.raw_image = None self.raw_image = None
@@ -69,7 +66,7 @@ class RoverVideoReceiver(QtCore.QThread):
self.__set_local_callbacks() self.__set_local_callbacks()
def run(self): def run(self):
self.logger.debug("Starting \"%s\" Thread") self.logger.debug("Starting \"%s\" Camera Thread" % self.camera_title_name)
while self.run_thread_flag: while self.run_thread_flag:
if self.video_enabled: if self.video_enabled:
@@ -79,7 +76,7 @@ class RoverVideoReceiver(QtCore.QThread):
self.msleep(18) self.msleep(18)
self.logger.debug("Stopping \"%s\" Thread") self.logger.debug("Stopping \"%s\" Camera Thread" % self.camera_title_name)
def __show_video_enabled(self): def __show_video_enabled(self):
if self.new_frame: if self.new_frame:
@@ -98,14 +95,16 @@ class RoverVideoReceiver(QtCore.QThread):
self.new_frame = False self.new_frame = False
def __on_image_update_ready(self): def __on_image_update_ready(self):
self.video_display_label.setPixmap(self.pixmap) pass
# self.video_display_label.setPixmap(self.pixmap)
def __image_data_received_callback(self, raw_image): def __image_data_received_callback(self, raw_image):
self.raw_image = raw_image self.raw_image = raw_image
self.new_frame = True self.new_frame = True
def __set_local_callbacks(self): def __set_local_callbacks(self):
self.video_display_label.mouseDoubleClickEvent = self.toggle_video_display pass
# self.video_display_label.mouseDoubleClickEvent = self.toggle_video_display
def toggle_video_display(self, _): def toggle_video_display(self, _):
if self.video_enabled: if self.video_enabled:

View File

@@ -7,9 +7,11 @@ import sys
from PyQt5 import QtWidgets, QtCore, QtGui, uic from PyQt5 import QtWidgets, QtCore, QtGui, uic
import signal import signal
import rospy import rospy
import logging
import qdarkstyle import qdarkstyle
# Custom Imports # Custom Imports
import Framework.StartupSystems.ROSMasterChecker as ROSMasterChecker
import Framework.LoggingSystems.Logger as Logger import Framework.LoggingSystems.Logger as Logger
import Framework.VideoSystems.RoverVideoCoordinator as RoverVideoCoordinator import Framework.VideoSystems.RoverVideoCoordinator as RoverVideoCoordinator
@@ -55,6 +57,8 @@ class GroundStation(QtCore.QObject):
LEFT_SCREEN_ID = 0 LEFT_SCREEN_ID = 0
RIGHT_SCREEN_ID = 1 RIGHT_SCREEN_ID = 1
exit_requested_signal = QtCore.pyqtSignal()
start_threads_signal = QtCore.pyqtSignal() start_threads_signal = QtCore.pyqtSignal()
connect_signals_and_slots_signal = QtCore.pyqtSignal() connect_signals_and_slots_signal = QtCore.pyqtSignal()
kill_threads_signal = QtCore.pyqtSignal() kill_threads_signal = QtCore.pyqtSignal()
@@ -63,7 +67,11 @@ class GroundStation(QtCore.QObject):
# noinspection PyArgumentList # noinspection PyArgumentList
super(GroundStation, self).__init__(parent) super(GroundStation, self).__init__(parent)
rospy.init_node("ground_station") # ##### Setup the Logger Immediately #####
self.logger_setup_class = Logger.Logger(console_output=True) # Doesn't need to be shared
# ########## Get the Pick And Plate instance of the logger ##########
self.logger = logging.getLogger("groundstation")
self.shared_objects = { self.shared_objects = {
"screens": {}, "screens": {},
@@ -71,7 +79,7 @@ class GroundStation(QtCore.QObject):
"threaded_classes": {} "threaded_classes": {}
} }
# ###### Instantiate Left And Right Screens ##### # ###### Instantiate Left And Right Screens ######
self.shared_objects["screens"]["left_screen"] = \ self.shared_objects["screens"]["left_screen"] = \
self.create_application_window(UI_FILE_LEFT, "Rover Ground Station Left Screen", self.create_application_window(UI_FILE_LEFT, "Rover Ground Station Left Screen",
self.LEFT_SCREEN_ID) # type: ApplicationWindow self.LEFT_SCREEN_ID) # type: ApplicationWindow
@@ -80,34 +88,27 @@ class GroundStation(QtCore.QObject):
self.create_application_window(UI_FILE_RIGHT, "Rover Ground Station Right Screen", self.create_application_window(UI_FILE_RIGHT, "Rover Ground Station Right Screen",
self.RIGHT_SCREEN_ID) # type: ApplicationWindow self.RIGHT_SCREEN_ID) # type: ApplicationWindow
# ##### Instantiate Simple Classes ##### # ###### Initialize the Ground Station Node ######
self.logger_setup_class = Logger.Logger(console_output=True) # Doesn't need to be shared rospy.init_node("ground_station")
# ##### Instantiate Threaded Classes ##### # ##### Instantiate Regular Classes ######
# ##### Instantiate Threaded Classes ######
self.__add_thread("Video Coordinator", RoverVideoCoordinator.RoverVideoCoordinator(self.shared_objects)) self.__add_thread("Video Coordinator", RoverVideoCoordinator.RoverVideoCoordinator(self.shared_objects))
# self.__add_thread("Primary Video",
# RoverVideoReceiver.RoverVideoReceiver(
# self.shared_objects,
# self.shared_objects["screens"]["right_screen"].primary_video_label,
# "/cameras/main_navigation/"))
# self.__add_thread("Secondary Video",
# RoverVideoReceiverOld.VideoTest(
# self.shared_objects,
# self.shared_objects["screens"]["right_screen"].secondary_video_label,
# (640, 360),
# sub_path="/cameras/chassis/image_640x360/compressed"))
# self.__add_thread("Tertiary Video",
# RoverVideoReceiverOld.VideoTest(
# self.shared_objects,
# self.shared_objects["screens"]["right_screen"].tertiary_video_label,
# (640, 360),
# sub_path="/cameras/undercarriage/image_640x360/compressed"))
self.connect_signals_and_slots_signal.emit() self.connect_signals_and_slots_signal.emit()
self.__connect_signals_to_slots() self.__connect_signals_to_slots()
self.start_threads_signal.emit() self.start_threads_signal.emit()
def ___ros_master_running(self):
checker = ROSMasterChecker.ROSMasterChecker()
if not checker.master_present(5):
self.logger.debug("ROS Master Not Found!!!! Exiting!!!")
QtGui.QGuiApplication.exit()
return False
return True
def __add_thread(self, thread_name, instance): def __add_thread(self, thread_name, instance):
self.shared_objects["threaded_classes"][thread_name] = instance self.shared_objects["threaded_classes"][thread_name] = instance
instance.setup_signals(self.start_threads_signal, self.connect_signals_and_slots_signal, instance.setup_signals(self.start_threads_signal, self.connect_signals_and_slots_signal,
@@ -121,8 +122,8 @@ class GroundStation(QtCore.QObject):
self.kill_threads_signal.emit() self.kill_threads_signal.emit()
# Wait for Threads # Wait for Threads
for thread in self.threads["threaded_classes"]: for thread in self.shared_objects["threaded_classes"]:
self.threads["threaded_classes"][thread].wait() self.shared_objects["threaded_classes"][thread].wait()
QtGui.QGuiApplication.exit() QtGui.QGuiApplication.exit()
@@ -152,13 +153,26 @@ class GroundStation(QtCore.QObject):
if __name__ == "__main__": if __name__ == "__main__":
signal.signal(signal.SIGINT, signal.SIG_DFL) # This allows the keyboard interrupt kill to work properly signal.signal(signal.SIGINT, signal.SIG_DFL) # This allows the keyboard interrupt kill to work properly
# ########## Start the QApplication Framework ##########
application = QtWidgets.QApplication(sys.argv) # Create the ase qt gui application application = QtWidgets.QApplication(sys.argv) # Create the ase qt gui application
application.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) application.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
# ########## Set Organization Details for QSettings ##########
QtCore.QCoreApplication.setOrganizationName("OSURC") QtCore.QCoreApplication.setOrganizationName("OSURC")
QtCore.QCoreApplication.setOrganizationDomain("http://osurobotics.club/") QtCore.QCoreApplication.setOrganizationDomain("http://osurobotics.club/")
QtCore.QCoreApplication.setApplicationName("groundstation") QtCore.QCoreApplication.setApplicationName("groundstation")
ground_station = GroundStation() # ########## Check ROS Master Status ##########
master_checker = ROSMasterChecker.ROSMasterChecker()
if not master_checker.master_present(5):
message_box = QtWidgets.QMessageBox()
message_box.setWindowTitle("Rover Ground Station")
message_box.setText("Connection to ROS Master Failed!!!\n" +
"Ensure ROS master is running or check for network issues.")
message_box.exec_()
exit()
# ########## Start Ground Station If Ready ##########
ground_station = GroundStation()
application.exec_() # Execute launching of the application application.exec_() # Execute launching of the application