Skip to content

Commit

Permalink
Organized files and added comments
Browse files Browse the repository at this point in the history
  • Loading branch information
keithmk authored and keithmk committed Feb 16, 2024
1 parent cdad43f commit 47ef621
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 80 deletions.
192 changes: 117 additions & 75 deletions mil_common/utils/mil_tools/scripts/mil-preflight/main.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,42 @@
################################################################################
# File name: main.py
# Author: Keith Khadar
# Description: This file is the entry point to preflight.
################################################################################
# ----- Imports ----- #
# ----- Preflight -----#
# ----- Console -----#
import subprocess
import time

import menus

# ----- ROS -----#
import rosnode
import rospy
import rostopic
import tests
from PyInquirer import prompt
from rich.console import Console
from rich.progress import Progress, track
from rich.table import Table

# Custom message imports
from subjugator_msgs.msg import ThrusterCmd

# ----- Variables ----- #
# ----- Timeouts -----#
node_timout = 5 # seconds
topic_timout = 5 # seconds
actuator_timout = 5 # seconds

# ----- Reports -----#
report = []

hardwareChecklist = [
{
"type": "checkbox",
"message": "Hardware Checklist:",
"name": "HardwareTests: \nPlease check that all of the following are in working order. \nYou cannot continue until everything has been checked.",
"choices": [
{"name": "check thing 1"},
{"name": "check thing 2"},
{"name": "check thing 3"},
{"name": "check thing 4"},
{"name": "check thing 5"},
],
},
]

topics = [
# "/camera/front/right/image_raw",
# "/camera/down/image_raw",
# "/camera/front/left/image_raw",
# "/dvl",
# "/depth",
# "/imu/data_raw",
# "/imu/mag",
]

nodes = ["/odom_estimator"]

actuatorsList = [
(
"/thrusters/thrust",
[
ThrusterCmd(name="FLH", thrust=60.0),
ThrusterCmd(name="FLV", thrust=60.0),
ThrusterCmd(name="FRH", thrust=60.0),
ThrusterCmd(name="FRV", thrust=60.0),
ThrusterCmd(name="BLH", thrust=60.0),
ThrusterCmd(name="BLV", thrust=60.0),
ThrusterCmd(name="BRH", thrust=60.0),
ThrusterCmd(name="BRV", thrust=60.0),
],
),
]

# ----- Main Routine ----- #


def main():
# Clear Screen and Display Start menu
subprocess.run("clear", shell=True)
clear_screen()

# Print Info about Preflight
Console().print(menus.info_page)
Expand All @@ -75,6 +48,8 @@ def main():
# Select the mode and run it
if mode == "Run Preflight Full Test":
fullTest()
if mode == "View Report":
viewReport()
if mode == "Exit":
subprocess.run("clear", shell=True)
return
Expand All @@ -83,55 +58,78 @@ def main():
main()


# ----- Subroutines ----- #

# ----- Modes -----#


def fullTest():
### Complete the hardware tests ###

while True:
subprocess.run("clear", shell=True)
answers = prompt(hardwareChecklist)
# Clear the screen and display the hardware checklist
clear_screen()
Console().print(menus.hardware_desc)
respond = prompt(menus.hardwareChecklist)

# If everything has been checked off
if len(next(iter(answers.values()))) == 5:
break
# Filter the response and store checklist to the report
answers = []
for i in range(len(tests.hardware)):
if tests.hardware[i] in next(iter(respond.values())):
answers.append((tests.hardware[i], True))
else:
menu_ans = prompt(menus.incomplete_continue)
if next(iter(menu_ans.values())) is True:
# Continue even though everything has not been checked off
break
else:
# Go back to main menu
return
answers.append((tests.hardware[i], False))
createResult(answers, "Hardware Checklist")

# Check if the list is incomplete. If so prompt user for comfirmation to continue
if len(next(iter(respond.values()))) != len(tests.hardware):
menu_ans = prompt(menus.incomplete_continue)
if next(iter(menu_ans.values())) is False:
return

### Complete Software Tests ###

subprocess.run("clear", shell=True)
# Clear the screen
clear_screen()

# Check that ROS is running!
try:
rostopic._check_master()
except Exception:
Console().print("[bold] ROS not running! Please try again later[/]")
menu_ans = prompt(menus.press_anykey)
return

# Initialize the ROS node
rospy.init_node("preflight")

# Print Node Screen description
Console().print(menus.node_desc)

# Check Nodes
answers = []
for node in track(nodes, description="Checking Nodes..."):
for node in track(tests.nodes, description="Checking Nodes..."):
# Try and ping the nodes
try:
answers.append((node, rosnode.rosnode_ping(node, node_timout)))
except Exception:
answers.append((node, False))

print_results(answers)
# Clear the screen, print and save the response to the report
print_results(answers, "Node Liveliness")

# Prompt the user to continue to next test
menu_ans = prompt(menus.continue_question)
if next(iter(menu_ans.values())) is False:
# Go back to main menu
return

# Print Topic screen description
clear_screen()
Console().print(menus.topic_desc)

# Check Topics
answers = []
for topic in track(topics, description="Checking Topics..."):
for topic in track(tests.topics, description="Checking Topics..."):
# Check for messages on the topics
try:
topicType, topicStr, _ = rostopic.get_topic_class(topic) # get topic class
Expand All @@ -140,21 +138,26 @@ def fullTest():
topicType,
topic_timout,
) # try to get a message from that topic
answers.append({topic: True})
answers.append((topic, True))
except Exception:
answers.append({topic: False})
print_results(answers)
answers.append((topic, False))

# Clear the screen, print and save the response to the report
print_results(answers, "Topic Liveliness")

# Prompt the user to continue to next test
menu_ans = prompt(menus.continue_question)
if next(iter(menu_ans.values())) is False:
# Go back to main menu
return

### Actuators Test ###
# Print Actuators Screen description
subprocess.run("clear", shell=True)
Console().print(menus.node_desc)

answers = []
for actuator in actuatorsList:
for actuator in tests.actuatorsList:
try:
# Confirm that it is safe to run this actuator
Console().print(menus.safety_check, actuator[0])
Expand Down Expand Up @@ -185,18 +188,57 @@ def fullTest():
except Exception:
answers.append((actuator[0], False))

print_results(answers)
menu_ans = prompt(menus.press_anykey)
# Clear the screen, print and save the response to the report
print_results(answers, "Actuator Tests")
prompt(menus.press_anykey)
return


def viewReport():
# Clear the screen
clear_screen()

# Check that there is a report
if len(report) == 0:
Console().print(
"[bold]No report![/].\nPlease generate a report by running a full test.",
)
prompt(menus.press_anykey)
return
# Generate the report
for result in report:
Console().print(result)
prompt(menus.press_anykey)
return


def print_results(systems):
# ----- Helper -----#


def createResult(systems, name):
# Generates a table to hold information about each system
result = Table(title=f"[bold]{name}[/]")
result.add_column("System Name", justify="center", style="cyan", no_wrap=True)
result.add_column("Status", justify="center", style="magenta", no_wrap=True)

# Populates the table
for system, status in systems:
status_text = "[green]✔[/] Working" if status else "[red]❌[/] Not Working"
result.add_row(system, status_text)
report.append(result)

return result


def print_results(systems, name):
clear_screen()
result = createResult(systems, name)
Console().print(result)


def clear_screen():
subprocess.run("clear", shell=True)
for name, status in systems:
if status:
Console().print(f"{name}: [green]✔[/] Working")
else:
Console().print(f"{name}: [red]❌[/] Not Working")
Console().print(menus.title)


if __name__ == "__main__":
Expand Down
41 changes: 36 additions & 5 deletions mil_common/utils/mil_tools/scripts/mil-preflight/menus.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
################################################################################
# File name: menus.py
# Author: Keith Khadar
# Description: This file is used to store all the menus used by prefligh
# Description: This file is used to store all the menus used by preflight
################################################################################

# ----- Imports -----#
import tests

# ----- Home Page -----#
info_page = """
title = """
[bold green]Preflight Program - Autonomous Robot Verification[/bold green]
"""
info_page = """
Welcome to the Preflight Program, a tool inspired by the preflight checklists used by pilots before flying a plane. This program is designed to verify the functionality of all software and hardware systems on your autonomous robot. It ensures that everything is in working order, allowing you to safely deploy your robot with confidence.\n
[italic]Authors:[/italic]
Keith Khadar
Anthony Liao
Joshua Thomas\n
Joshua Thomas
Maanas Kotha\n
"""


Expand Down Expand Up @@ -44,6 +48,7 @@
"type": "confirm",
"name": "continue",
"message": "Press any key to continue.",
"confirm": False,
},
]

Expand All @@ -62,9 +67,35 @@
},
]


# ----- Software Screen -----#
node_desc = """
Welcome to the [bold]ROS Node Liveliness Test screen[/]. This screen allows you to verify the liveliness of ROS nodes within the system. ROS nodes are essential components responsible for communication and control within the robot\'s architecture. Use this screen to ensure that all necessary nodes are running and responsive for proper system functionality.
"""
topic_desc = """
Welcome to the Topic Monitoring screen. This screen allows you to monitor the topics in the ROS system. In a ROS (Robot Operating System) environment, topics serve as channels through which nodes communicate by publishing and subscribing to messages. Monitoring topics enables you to verify that sensors are actively publishing their data.
"""

# ----- Hardware Screen -----#
hardware_desc = """
Welcome to the [bold]Hardware Inspection Checklist[/] page of our preflight app! This checklist is designed to ensure that all critical hardware components of your robot are thoroughly inspected before each operation. By completing this checklist, you contribute to the safety and reliability of the robot during its mission. Please carefully examine each item listed below to verify its condition and functionality.
"""
hardwareChecklist = [
{
"type": "checkbox",
"message": "Hardware Checklist:",
"name": "HardwareTests: \nPlease check that all of the following are in working order.",
"choices": [{"name": item} for item in tests.hardware],
},
]

# ----- Actuators Screen -----#
actuator_desc = """
Welcome to the [bold]Actuator Test Screen[/]. This screen allows you to test the functionality of various actuators on the robot. Actuators play a crucial role in the movement and operation of the robot. Use this screen with caution and follow the instructions carefully to avoid any accidents or damage to the robot.
\n[bold red]Caution:[/bold red] Actuators can be dangerous if mishandled. Please be careful when testing them, as they have the potential to cause harm or injury. For example, thrusters, when spinning, could chop off someone's finger. Always follow safety protocol and guidelines.
"""
safety_check = """
MAKE SURE THAT EVERYONE'S FINGERS ARE CLEAR!! Is it safe to run the following actuator?
[bold][yellow]Ensure that all fingers are clear of the area![/yellow][/bold] Is it safe to operate the following actuator?
"""

actuator_check = """
Expand Down
Loading

0 comments on commit 47ef621

Please sign in to comment.