Skip to content

Commit

Permalink
Added Publisher, specified goals in Homepage.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Vaibhav-Hariani committed Apr 10, 2024
1 parent a7dd3a8 commit 49a334f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 52 deletions.
61 changes: 61 additions & 0 deletions ros2/UI/ 🚗 Homepage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import streamlit as st
from streamlit import runtime
from streamlit.web import cli as stcli
import sys


def runner():
st.header("Welcome to the IGVC Homepage!")
st.markdown('''
Please select an option on the sidebar to the right: This specifies which UI file you'd like to run
Streamlit supports fast reloads: Just refresh the python script to get going!
Docs are here: https://docs.streamlit.io/library/api-reference
''')
st.divider()
st.markdown('''
For the freshmen: This UI is designed to serve multiple purposes
#1. We need a way to render all of the openCV data we have: This is stuff like the lane or object detection.
#2. We need a way to tune parameters in an easy way, without refreshing every single page for small little tweaks.
#3. We need to be able to control the state machines on the car: Each of the function tests is effectively it's own state machine.
We need to be able to control which test we're in, and visualize any important data in a direct manner.
#4. It makes us look professional, and adds quite a bit of useful fluff for our design report.
''')
st.divider()
st.markdown('''
Of course, not a lot of this is in your control: We haven't built the state machines or finished all of our algorithms.
However, Lane Detection is in the perfect place for you to familiarize yourself with both streamlit and the entire tech stack.
I'm detailing all immediate tasks here: Please allocate amongst yourselves.
I have taken the liberty of building a bespoke ros2 publisher and subscriber system (was not trivial), that should provide a solid framework.
However, it will get extremely tedious to build a proper UI if you don't exploit some of the advantages of python.
Read about list comprehension and get good.
#1: Connecting all datastreams from the lane_detection algorithm into here.
Everything that is cv.imshow() is rendered in that, in a clean and effective manner.
#2: Parametrizing all constants in that: anything that had a slider should be here, and it should be published.
#3: Beautifying, and building more tabs & systems so this is the only interface we need with the car.
We should not be opening up or handling multiple windows with the judges.
Debugging systems, sensor messages (E.g IMU, CAN) should all live here.
''')
st.warning("FIRST PRIORITY: https://docs.streamlit.io/develop/api-reference/widgets/st.page_link CHANGE THE PAGES SO NO MORE EMOJIS")


# This allows the system to run without being in a dedicated streamlit session:
if __name__ == "__main__":
if runtime.exists():
st.set_page_config(
page_title="IGVC Homepage",
page_icon="🚗")
st.sidebar.success("Select a System above.")
runner()
else:
sys.argv = ["streamlit", "run", sys.argv[0]]
sys.exit(stcli.main())
28 changes: 0 additions & 28 deletions ros2/UI/Homepage.py

This file was deleted.

72 changes: 48 additions & 24 deletions ros2/UI/pages/🛣 Lane_Detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from rclpy.qos import qos_profile_sensor_data
from cv_bridge import CvBridge
import time
from std_msgs.msg import String


## This class currently subscribes to some topics in cam_publisher, which I used to test. Please rewrite for lane Detection.
class Image_Handler(Node):

def __init__(self):
self._tabs = None
self._img = None
Expand All @@ -27,27 +27,41 @@ def __init__(self):
self.hsvData_callback,
qos_profile_sensor_data)


def tabs(self,tabs):
def tabs(self, tabs):
self._tabs = tabs
# SRC is cv2.VideoCapture FOR NOW: Will need to be tweaked in the future to rossify
self._frame_containers = [tab.empty() for tab in self._tabs]


def camData_callback(self, msg_in):
raw = msg_in
img = self._bridge.imgmsg_to_cv2(raw)
self._frame_containers[0].image(img)

def hsvData_callback(self, msg_in):
raw = msg_in
img = self._bridge.imgmsg_to_cv2(raw)
self._frame_containers[1].image(img)


#This class is your publisher: Flesh it out and integrate accordingly
class Publisher(Node):
def __init__(self):
super().__init__('Streamlit_Button_Publisher')
self.logger = self.get_logger()
self.button_pub = self.create_publisher(String, '/streamlit/button',10)

def demo_publish():
msg = String()
msg.data = "Streamlit Button!"
st.session_state["pub_node"].button_pub.publish(msg)
st.success("Message Published!")




# See ../../ros2/src/lanefollowingtest/LaneDetection.py
# This page should render ALL images in there, as well as publish
# This page should render ALL images in there, as well as publish important update data
if __name__ == "__main__":
#How we Configure the page
st.set_page_config(
page_title="Lane Detection",
page_icon="🛣")
Expand All @@ -58,20 +72,30 @@ def hsvData_callback(self, msg_in):
"This should render all of the images related to Lane Detection, and relevant parameters.")
tabs = st.tabs(["Original", "HSV", "Sliding Windows"])

if "node" not in st.session_state:
try:
rclpy.init()
except RuntimeError:
st.warning("something went wrong performance may be degraded. Try restarting fully")
finally:
handler = Image_Handler()
handler.tabs(tabs)
st.session_state["node"] = handler

#This hunk initializes the ROS2 nodes without breaking anything :)
if "sub_node" not in st.session_state:
try:
rclpy.init()
except RuntimeError:
st.warning(
"something went wrong performance may be degraded. Try restarting fully.")
finally:
handler = Image_Handler()
handler.tabs(tabs)
st.session_state["sub_node"] = handler
if "pub_node" not in st.session_state:
st.session_state["pub_node"] = Publisher()


st.button("Ros Topic Publisher Demo!",on_click=demo_publish)
# As this is an infinite loop, it should only be run at the end of the file.
if render:
while(True):
try:
rclpy.spin_once(st.session_state['node'])
time.sleep(0.01)
except:
st.warning("Something went wrong, perhaps tabs were clicked too quickly? Try restarting.")
break
while (True):
try:
rclpy.spin_once(st.session_state['sub_node'])
time.sleep(0.01)
except:
st.warning(
"Something went wrong, perhaps tabs were clicked too quickly? Try restarting.")
break

0 comments on commit 49a334f

Please sign in to comment.